Модель Django с несколькими внешними ключами

Я хочу создать список продуктов, которые классифицируются по области, потребности и категории продукта. Я создал 3 отдельные модели, которые отвечают друг на друга, чтобы пользователи могли легко добавлять категории и выбирать из выпадающего списка область и потребность.

На данный момент у меня есть 3 области и под каждой областью у меня есть потребности. Я хочу вывести список элементов из модели Area, под каждым элементом из модели Area все элементы из модели Need и под каждым элементом из модели Need все элементы из модели Product (только названия).

ProductCategory модель не используется здесь, но она нужна мне в другом месте и является соединителем между продуктами и областями/потребностями. Гораздо проще определить категории и просто выбирать их из выпадающего списка при добавлении нового продукта.

Мне нужно создать цикл, который покажет мне что-то вроде приведенного выше. Я знаю, что это не будет работать, но я хотел показать логику.

Мой вопрос в том, какой лучший подход для рендеринга чего-то подобного?

Как я могу получить category_area и category_need в моем классе и в моем html?

models.py

class Area(models.Model):
    title = models.CharField(max_length=75, blank=False)
    body = models.CharField(max_length=150, default='-', blank=False)
    publish = models.DateTimeField('publish', default=timezone.now)   

class Need(models.Model):
    title = models.CharField(max_length=75, blank=False, null=False, help_text='max 75 characters')
    body = models.CharField(max_length=150, default='-', blank=False)
    publish = models.DateTimeField(default=timezone.now)
    need_area = models.ForeignKey(Area, on_delete=models.CASCADE, related_name='need_area')

class ProductCategory(models.Model):
    title = models.CharField(max_length=400, blank=False, null=False, help_text='max 400 characters')
    body = models.TextField(default='-')
    publish = models.DateTimeField('publish', default=timezone.now)
    category_area = models.ForeignKey(Area, on_delete=models.CASCADE, related_name='category_area', null=True)
    category_need = models.ForeignKey(Need, on_delete=models.CASCADE, related_name='category_need', null=True)

class Product(models.Model):
    id = models.AutoField(primary_key=True)
    title = models.CharField(max_length=400, blank=False)
    category = models.ForeignKey(ProductCategory, on_delete = models.CASCADE, blank=True, related_name='products')

    def get_absolute_url(self):
        return reverse("product", kwargs={'slug': self.slug})

views.py

class SearchProducts(LoginRequiredMixin, ListView):
    login_url = 'login'
    redirect_field_name = 'login'
    template_name = 'hubble/search/manual_search.html'
    model = Product
    queryset = Product.objects.all()
    
    def get_context_data(self, **kwargs):
            context = super(SearchProducts, self).get_context_data(**kwargs)
            product_results = ProductCategory.objects.prefetch_related("products").all()
            context['product_results'] = product_results
            return context

product_search.html

    <div>
    {% for area in product_results %}
        <h6>{{area.title}}</h6>
    {% endfor %}
    </div>

Вы можете prefetch_related все обратные отношения и сделать итерацию, подобную этой:

areas = Area.objects.prefetch_related('need_area__category_need__products')

for area in areas:
    # iterate through each instance of Area
    for need in area.need_area.all():
        # iterate through  each instance of Need for the given area
        for product_category in need.category_need.all():
            # iterate through each instance of ProductCategory for the given need
            for product in product_category.products.all():
                # iterate through each instance of product for the given product category
Вернуться на верх