I am building a django website that displays the prices of items in a shop. Each item belongs to a category so I mande category a foreign key that can have one or more items.
`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`
However, in the html, I am unable to obtain both the category and the shop item
I tried the following...
`---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 %}`
I was hoping this would help me create a table where all the items are sorted below their respective categories but I got an error instead:
TemplateSyntaxError at / Invalid block tag on line 18: 'used_category', expected 'endblock'. Did you forget to register or load this tag?
CodePudding user response:
You can't create and update a list within the template, but you can prepare the data in the view function, then iterate over your items differently.
Start by making sure the categories are in your template context. To avoid n 1 queries, prefetch the related items also. In your view:
context["categories"] = (
Category.objects.exclude(shop_items=None)
.prefetch_related("shop_items")
)
Then in the template iterate over the categories:
{% 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 The related name shop_items
may not work here. To make sure it does, you can manually set the related_name on your foreign key. At the same time I would suggest changing itemName
to just 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
CodePudding user response:
You need to create a view function which will pass the required Models information to the Template, thus completing the Model - View - Template (MVT) method which django runs on.