Есть ли способ изолировать внешний ключ от связанной с ним модели с помощью django?

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

`class Category(models.Model):
     category = models.CharField(max_length=64)

     def __str__(self):
        return self.category

class ShopItem(models.Model):
    itemName = models.CharField(max_length=64)
    price = models.IntegerField()
    category = models.ForeignKey(Category, on_delete=models.CASCADE)

    def __str__(self):
        return self.itemName`

Однако в html я не могу получить ни категорию, ни товар магазина

Я попробовал следующее...

`---snip---

    {% used_category = [] %}
    {% for item in shopitem_list %}
        {% if item.category not in used_category %}
            <tr>
                <td>item.category</td>
                <td></td>
                <td></td>
            </tr>
            <tr>
                {% for rel_item in shopitem_list %}
                    {% if rel_item.category == item.category %}
                        <td></td>
                        <td>rel_item.itemName</td>
                        <td>rel_item.category</td>
                    {% endif %}
                {% enfor %}
            </tr>
        {% endif %}
    {% endfor %}`

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

TemplateSyntaxError at /. Недопустимый тег блока в строке 18: 'used_category', ожидается 'endblock'. Вы забыли зарегистрировать или загрузить этот тег?

Вы не можете создавать и обновлять список в шаблоне, но вы можете подготовить данные в функции просмотра, а затем перебирать элементы по-другому.

Начните с того, что убедитесь, что категории находятся в контексте вашего шаблона. Чтобы избежать n+1 запросов, выполните предварительную выборку связанных элементов. В вашем представлении:

    context["categories"] = (
        Category.objects.exclude(shop_items=None)
        .prefetch_related("shop_items")
    )

Затем в шаблоне перебираем категории:

    {% for category in categories %}
            <tr>
                <td colspan="3">{{ category.category }}</td>
            </tr>
            <tr>
                {% for item in category.shop_items %}
                        <td></td>
                        <td>{{ item.itemName }}</td>
                        <td>{{ item.price }}</td>
                {% enfor %}
            </tr>
    {% endfor %}

NB Связанное имя shop_items здесь может не работать. Чтобы убедиться в этом, вы можете вручную установить related_name для вашего внешнего ключа. В то же время я бы предложил изменить itemName на просто name:

class ShopItem(models.Model):
    name = models.CharField(max_length=64)
    price = models.IntegerField()
    category = models.ForeignKey(Category, on_delete=models.CASCADE, related_name="shop_items")

    def __str__(self):
        return self.name

Вам нужно создать функцию представления, которая будет передавать необходимую информацию о модели в шаблон, тем самым завершая метод Модель - Представление - Шаблон (MVT), по которому работает django.

Вернуться на верх