querying foreignkey nested for loop django

风流意气都作罢 提交于 2021-02-10 10:55:30

问题


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.

  1. 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?

  1. 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:


  1. 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.
  1. select_related() expects a fieldname as a paramter. So use a field name that exists on the Item model. Like:

    select_related('category')

  2. Where's the meal? May be you can proceed from there though.



来源:https://stackoverflow.com/questions/43770138/querying-foreignkey-nested-for-loop-django

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!