问题
I am trying to return a list of categories for a business, and for each category I would like to list all the items related to the category.
I was returning all of my items, not by category, but I have decided I want them sorted by category. This is what I have tried (among other attempts as well) I simply am having trouble getting the items into there categories. This is my latest attempt
In my models.py I have
Business(models.Model):
name = models.CharField(max_length=100)
address = models.CharField(max_length=100)
logo = models.CharField(max_length=300)
ItemCategory(models.Model):
name = models.CharField(max_length=50)
Item(models.Model):
name = models.CharField(max_length=100)
business = models.ForeignKey(Business)
category = models.ForeignKey(ItemCategory)
short_description = models.CharField(max_length=250)
in my views.py
def business_profile(request, business_id):
items = Item.objects.filter(business_id = business_id).select_related('itemcategory')
return render(request, 'business_profile.html', {"items": items})
in my template I am trying
{% for itemcategory in items.itemcategory_set.all %}
{{ itemcategory.name }}
{% for item in itemcategory %}
{{ item.name }} <br>
{{ item.short_description }}
{% endfor %}
{% endfor %}
From my research into other questions and reading the documents, i felt this would be right.. However from my results I can not get the correct output in my template.
- Would this be the correct practice? Or should I try getting the categories first with
categories = ItemCategory.objects.filter(business = business_id)
and then possibly add a select_related('item') to process all the items for the category?
- When I refer to data in the template but my model has 2 words (ItemCategory) - for instance when I move backward for a foreign key or use the model in select_related('') - would I use item_category or do you simply use itemcategory with no underscore?
UPDATE: I answered below in comment with explanation.
回答1:
To list the items by category, I used @yusuf.oguntola's idea and initially got the business with .get(), then I created a queryset to get all the items. My function in views.py included
business = Business.objects.get(id = business_id)
items = business.item_set.all().order_by('category')
note: the business_id was passed in url pattern
However, the key change was in my template. I found this awesome built in functionality for templates in the django documents here
I implemented it in template like so...
{% regroup items by category as category_list %}
<ul>
{% for category in category_list %}
<li>{{ category.grouper }}
<ul>
{% for item in category.list %}
<li>{{ item.name }}<br> {{ item.short_description }}</li>
{% endfor %}
</ul>
</li>
{% endfor %}
</ul>
One of the most important parts is you have to have order_by() and put the parameter of the field you are ordering by - in my case, category. If this is not included, it will simply put the items listed in chronological order and will repeat your field instance.
回答2:
items = Item.objects.filter(business_id = business_id)
is wrong. You should rather say:items = Item.objects.filter(business__id = business_id) #Notice the double underscore.
You may also rather get the business and simply say:
business.item_set.all() #This would retrieve all Item for the business.
select_related()
expects a fieldname as a paramter. So use a field name that exists on the Item model. Like:select_related('category')
Where's the meal? May be you can proceed from there though.
来源:https://stackoverflow.com/questions/43770138/querying-foreignkey-nested-for-loop-django