I have a question.
In my view, I return a dataset which includes:
Category
Product
Price
I want to say something like the below, where I show UI elements related to a category as a whole.
is it possible?
{% for item.category in products %}
Not directly. You would do
{% for item in products %}
...
{{ item.category}}
Or if item.category is itself an iterable you can nest loops. If it's the set of related objects you need a .all (c.f. python obj.foo_set.all() )
{% for item in products %}
...
{% for category in item.category.all %}
{% for item in products %}
{{item.Category}}
{{item.Product}}
{{item.Price}}
{% endfor %}
Related
I have a QuerySet with several entries order.order_items.all. I want to check in my template if any of these items in my list contain the foreign_key discount. After one is found, I want to display that a discount_code was used for the order. How would you solve this?
Example:
<QuerySet [OrderItem: #k9ukvrfvjk - 1x Test Ticket 1, OrderItem: #k9ukvrfvjk - 1x Test Ticket 2]>
Rather than doing it in Template, I think its better to do it in the view. For example:
context['discount'] = order.order_items.filter(discount_id=<discount_id>).exists()
return render(request, 'template', context=context)
and in template:
{% if discount %}
// discounted related codes
{% endif %}
Update
Maybe you can get it simply by:
{% item in order.order_items.all %}
{% if item.discount %}
{{ item.discount.discount_code }}
{% endif %}
{% endfor %}
I have 2 models Category and Spending where Category is one of the Spending fields.
User can create custom categories and add spending on the webpage.
The question is, how to filter spendings by categories in Template?
I have:
{% for category in categories %}
{% for spending in spendings %} 'I want this FOR have only spendings from this category.'
I know how to filter objects with Object.objects.filter() but I am not sure it applies here, because categories are dynamic here
Use the reverse relation. You haven't shown your models, but presumably there is a foreign key from Spending to Category. If so:
{% for spending in category.spending_set.all %}
You can do this way.
{% for category in categories %}
{% for spending in category.spending_set.all %}
{{spending}}
{% endfor %}
{% endfor %}
so i have a model which is,
class Category(SmartModel):
item=models.ManyToManyField(Item)
title=models.CharField(max_length=64,help_text="Title of category e.g BreakFast")
description=models.CharField(max_length=64,help_text="Describe the category e.g the items included in the category")
#show_description=check box if description should be displayed
#active=check box if category is still avialable
display_order=models.IntegerField(default=0)
def __unicode__(self):
return "%s %s %s %s " % (self.item,self.title, self.description, self.display_order)
and as you may see, it has a manytomany field
item=models.ManyToManyField(Item)
i want to return all the items in a template, here is my views.py for this
def menu(request):
categorys= Category.objects.all()
items= categorys.all().prefetch_related('item')
context={
'items':items,
'categorys':categorys
}
return render_to_response('menu.html',context,context_instance=RequestContext(request))
here is how am doing it in the templates,
<ul>
{% for item in items %}
<li>{{ item.item }}
</li>
</ul>
{% endfor %}
after all this,this is what it is returning in my web page,
<django.db.models.fields.related.ManyRelatedManager object at 0xa298b0c>
what am i doing wrong,I have really looked around but all in vain, hoping you can help me out and thanking you in advance
Exactly, you have a many to many manager. You need to actually query something... like all()
{% for item in items %}
{% for i in item.item.all %}
{{ i }}
{% endfor %}
{% endfor %}
Based on your variable naming, I think you're confusing the results of prefetch_related as a bunch of items. It is in fact returning a QuerySet of Category objects.
So it would be more intuitive to call them categories.
{% for category in categories %}
{% for item in category.item.all %}
{{ item }} {# ...etc #}
Try to use:
categorys= Category.objects.prefetch_related('item').all()
And then in template:
{% for category in categorys %}
{% for item in category.item.all %}
{{ item }}
{% endfor %}
{% endfor %}
This is a hypothetical for simplicity. In my Django app I have models for Kit, KitSku, and Sku. The KitSku model associates a Sku with a Kit and also provides the quantity of that Sku in that kit. In the template I have something like:
<!-- SELECT * FROM kitsku_table WHERE kit_id = <Kit.id> -->
{% for kitsku in kit.kitsku_set.all %}
<!-- SELECT * FROM sku_table WHERE sku = <KitSku.sku> -->
<div>{{ kitsku.sku.name }}</div>
{% endfor %}
Now, the problem here is that Django is querying all of the KitSku rows and then it queries each sku within that for loop in a separate SQL query for each iteration.
Can I make the SQL query resulting from the kitsku_set.all() call perform a JOIN with the Sku model?
That first query needs to be more like:
SELECT * FROM kitsku_table k LEFT JOIN sku_table s ON (k.sku = s.sku)
WHERE k.kit_id = <Kit.id>
Do this type of logic in the view, and use select_related() to directly query the foreign keys
kitskus = Kit.objects.get(id=3).kitsku_set.select_related('sku')
return direct_to_template(request, "mytemplate.html", {'kitskus': kitskus})
Im just copying an answer for a similar question, but i think this is a much better approach.
view
newsletters = Newsletter.objects.prefetch_related('article_set').all()\
.order_by('-year', '-number')
return render_to_response('newsletter/newsletter_list.html',
{'newsletter_list': newsletters})
template
{% block content %}
{% for newsletter in newsletter_list %}
<h2>{{ newsletter.label }}</h2>
<p>Volume {{ newsletter.volume }}, Number {{ newsletter.number }}</p>
<p>{{ newsletter.article }}</p>
<ul>
{% for a in newsletter.article_set.all %}
<li>{{ a.title }}</li>
{% endfor %}
</ul>
{% endfor %}
{% endblock %}
Here is the complete explanation:
Hopes it helps
Iterating over related objects in Django: loop over query set or use one-liner select_related (or prefetch_related)
What's the best way to generate HTML which has a heading for each Category, and Products under that category in a Django template?
I toyed with the idea of having a passing a dictionary, or an ordered list...
Take a look at the regroup template filter
http://docs.djangoproject.com/en/dev/ref/templates/builtins/#regroup
With it you could do something like this:
{% regroup products by category as products_by_category %}
{% for c in products_by_category %}
<h1>{{c.grouper}}</h1>
<ul>
{% for p in c.list %}
<li>{{p.name}}</li>
{% endfor %}
</ul>
{% endfor %}
In addition to what #Wade suggests you can also add a method to your Category model to return the products it has.
Example..
class Category:
...
...
def get_products(self):
return Product.objects.filter(category=self)
Then in a template you can..
{% for category in categories %} # assuming categories is passed from the view.
{% for product in category.get_products %}
...
used a sorted list in the view code,
sorted(dom_obj.objects.all(), key=lambda d: d.sort_key)
and then used the filter tag
{% ifchanged %}<h1>{{ prod.cat }}</h1>{% endifchanged %}