Есть ли способ изолировать внешний ключ от связанной с ним модели с помощью 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.