Как отобразить продукт одного бренда в определенной категории?

помогите задушить этого питона уважаемые гуру! Есть три модели: Категории - Category, Brand-бренд и карточки продуктов - Card, связанные FK и с Category и Brand для удобной фильтрации. Сначала связал Brand через внешний ключ с Сategory, но при наполнении таблицы бд дублировались бренды, что вызывало ошибки и неудобство.

models.py

from django.db import models
from django.urls import reverse


class Category(models.Model):
    name_cat = models.CharField(max_length=200, db_index=True)
    slug = models.SlugField(max_length=200, unique=True, db_index=True, verbose_name='URL')

    class Meta:
        ordering = ('name_cat',)
        verbose_name = 'Категория'
        verbose_name_plural = 'Категории'

    def __str__(self):
        return self.name_cat

    def get_absolute_url(self):
        return reverse('cats', kwargs={'cat_id': self.pk})


class Brand(models.Model):
    name = models.CharField(max_length=200, db_index=True)
    slug = models.SlugField(max_length=200, db_index=True, unique=True, verbose_name='URL')

    class Meta:
        ordering = ('name',)
        verbose_name = 'Бренд'
        verbose_name_plural = 'Бренды'

    def __str__(self):
        return self.name

    def get_absolute_url(self):
        return reverse('brand', kwargs={'brand_id': self.pk})


class Card(models.Model):
    category = models.ForeignKey(Category, on_delete=models.CASCADE)
    brand = models.ForeignKey(Brand, on_delete=models.PROTECT)
    boots_model = models.CharField(max_length=100, db_index=True, verbose_name='Модель бутс')
    description = models.TextField(verbose_name='Описание')
    slug = models.SlugField(max_length=200, unique=True, db_index=True, verbose_name='URL')
    price = models.DecimalField(max_digits=10, decimal_places=2, verbose_name='Цена')
    image = models.ImageField(upload_to="photos/%Y/%m/%d/", blank=True)
    created = models.DateTimeField(auto_now_add=True, db_index=True)
    updated = models.DateTimeField(auto_now=True)
    size = models.DecimalField(max_digits=4, decimal_places=1, verbose_name='Размер')
    color = models.CharField(max_length=100, db_index=True, verbose_name='цвет')

    class Meta:
        ordering = ('-created',)
        verbose_name = 'Объявление'
        verbose_name_plural = 'Объявления'

    def __str__(self):
        return self.boots_model

    def get_absolute_url(self):
        return reverse('card', kwargs={'card_id': self.pk})

При отображении страницы brand.html выпадает так

То есть сортируется модель Card по id-шнику Brand, при этом не понимаю как во views.py отфильтровать текущую категорию, таким образом, чтобы карточки отображались текущей категории Бутсы и только текущего бренда. прошу посмотреть views.py и особенно обратить внимание на def show_brands(request, brand_id). Так как обработчик должен понимать, на какой странице Бренда мы сейчас находимся, привязал к id. В дальнейшем сделаю по slug, но сначала нужно разобраться с этим.

views.py

from django.http import HttpResponse
from django.shortcuts import render, get_object_or_404
from .models import Category, Brand, Card

def index(request):
    brands = Brand.objects.all()
    categories = Category.objects.all()
    cards = Card.objects.all()

    context = {
        'categories': categories,
        'brands': brands,
        'cards': cards
    }
    return render(request, 'mysite/index.html', context)

def show_categories(request, cat_id):
    brands = Brand.objects.all()
    categories = Category.objects.all()
    cards = Card.objects.filter(category__id=cat_id)

    context = {
        'categories': categories,
        'brands': brands,
        'cards': cards
    }
    return render(request, 'mysite/cats.html', context)

def show_brands(request, brand_id):
    brands = Brand.objects.filter(id=brand_id)
    categories = Category.objects.all()
    current_brand = Brand.objects.get(id=brand_id)
    cards = Card.objects.filter(brand_id=brand_id)


    context = {
        'categories': categories,
        'brands': brands,
        'cards': cards,
        'current_brand': current_brand
    }
    return render(request, 'mysite/brand.html', context)


def show_cards(request, card_id):
    brands = Brand.objects.all()
    categories = Category.objects.all()
    cards = Card.objects.get(id=card_id)

    context = {
        'categories': categories,
        'brands': brands,
        'cards': cards,
    }
    return render(request, 'mysite/card.html', context)

Резюмируя: не понимаю как через model.objects.filter зацепить по двум внешним ключам сделать выборку фильтра таким образом, чтобы отображалась нужная мне категория и текущий бренд.


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

Автор решения: Za Ars
# views.py
def show_from_cat_and_brand(request, *args, **kwargs):
    cat_id = kwargs.get('category_id')
    brand_id = kwargs.get('brand_id')

    cards = Card.objects.filter(brand_id=brand_id, category_id=cat_id)
    ...

В urls.py указываете, что ждете 2 аргумента-числа.

В результате фильтрации получите queryset содержащий карточки только из конкретной категории конкретного бренда

→ Ссылка