Как мне правильно разделить товар на женский и мужской?

Есть две большие категории (Женские и Мужские товары)

До этого у меня не было этого разделения (товар просто делился на кат.), сейчас появилась такая потребность

Что именно мне нужно изменить в моем коде, чтобы товар разделялся на женский и мужской и при клике например на женскую категорию товар разделялся и в самих категориях только для женщин ?

models.py

class Category(models.Model):
  name = models.CharField(max_length=200, db_index=True, verbose_name='Название')
  slug = models.SlugField(max_length=200, unique=True)

  class Meta:
    ordering = ('name',)
    verbose_name = 'категория'
    verbose_name_plural = 'категории'
    
  def __str__(self):
    return self.name
    
  def get_absolute_url(self):
    return reverse('shop:product_list_by_category', args=[self.slug])
    

class Product(models.Model):
  category = models.ForeignKey(Category, related_name='products', on_delete=models.CASCADE, 
  verbose_name='Категория')
  gender = models.CharField(max_length=15, choices=[('Ж', 'Женская'), ('М', 'Мужская'), ('У', 
 'Унисекс'), (None, 'Выберите принадлежность')], verbose_name='Принадлежность', blank=False, 
  null=True)
  name = models.CharField(max_length=200, db_index=True, verbose_name='Название')
  slug = models.SlugField(max_length=200, db_index=True)
  image = models.ImageField(upload_to='products/%Y/%m/%d', blank=True, verbose_name='Фото')
  image_2 = models.ImageField(upload_to='products/%Y/%m/%d', blank=True, verbose_name='Фото №2')
  image_3 = models.ImageField(upload_to='products/%Y/%m/%d', blank=True, verbose_name='Фото №3')
  image_4 = models.ImageField(upload_to='products/%Y/%m/%d', blank=True, verbose_name='Фото №4')
  description = models.TextField(blank=True, verbose_name='Описание')
  price = models.DecimalField(max_digits=10, decimal_places=2, verbose_name='Цена')
  available = models.BooleanField(default=True, verbose_name='Наличие')
  created = models.DateTimeField(auto_now_add=True, verbose_name='Создан')
  updated = models.DateTimeField(auto_now=True, verbose_name='Обновлен')

  class Meta:
    ordering = ('name',)
    index_together = (('id', 'slug'),)
    verbose_name_plural = 'Продукты'

  def __str__(self):
    return self.name
    
  def get_absolute_url(self):
    return reverse('shop:product_detail', args=[self.id, self.slug])

views.py

def product_list(request, category_slug=None):
  categories = Category.objects.all()
  products = Product.objects.filter(available=True)

  if category_slug:
    category = get_object_or_404(Category, slug=category_slug)
    products = products.filter(category=category)
  else:
    category = None

  sort_form = SortForm(request.POST or {'sort_form': request.session.get("need_sort")})
  if request.POST:
    if sort_form.is_valid():
        request.session["need_sort"] = sort_form.cleaned_data.get("sort_form")
  need_sort = request.session.get("need_sort")  
  if need_sort == 'ПУ':
    products = products.order_by('name')
  elif need_sort == 'ДТ':
    products = products.order_by('-created')
  elif need_sort == "ДЕД":
    products = products.order_by("price")
  elif need_sort == "ДОД":
    products = products.order_by("-price")

pages = Paginator(products, 18)
page_number = request.GET.get('page')
page_object = pages.get_page(page_number)
    
context = {'category': category, 'categories': categories, 'products': products, 'page_object': 
page_object, 'sort_form': sort_form}
return render(request, 'shop/product_list.html', context)

Ответы (1 шт):

Автор решения: Роман

Весь код писать не буду, покажу не примере категорий. Рекомендую использовать mptt.

class Category(MPTTModel):
        """Определяем категории для товара"""
        name = models.CharField(max_length=70, unique=True, verbose_name='Подкатегория')
        slug = models.CharField(max_length=100, unique='title', verbose_name='url')
        objects = models.Manager()
        parent = TreeForeignKey('self', on_delete=models.CASCADE, null=True, blank=True, related_name='children',
                                verbose_name='Главная категория')
    
    
        class Meta:
            ordering = ('tree_id','name')
    
        def get_absolute_url(self):
            if self.parent:
                return reverse('shop:category_url_with_subcat', args=[self.parent.slug, self.slug])
            else:
                return reverse('shop:category_url', args=[self.slug])
    
        def __str__(self):
            return self.name
    
    
    mptt.register(Category, order_insertion_by=['title'])

В модели Product лучше использовать TreeManyToManyField вместо models.ForeignKey, например, если это магазин обуви, то товар может относиться к нескольким категориям (например, обувь может быть женская, зимняя). Надеюсь суть ясна

→ Ссылка