Django how to list model objects date wise - django

I have a model from which I need to list all the objects from a given time period.
For example: 10-05-2014 to 10-12-2014
And then I need to display the objects date wise. Meaning first display objects created on the start_date(10-05-2014) up until end_date(10-12-2014)
For example:
10-05-2014:
objects list for that day
11-05-2014:
objects list for that day
and so on until end_date
Query:
MyModel.objects.unsettled.filter(
created_on__range=[start_date, end_date]
)
But my problem is how do I list the query set in increasing order by date wise in my template. So that all the objects created on same date will be shown under that date. In short I want to display the list in sections divided by date.
MyModel.objects.unsettled.filter(created_on__range=[start_date, end_date]).order_by("created_on"). But it will just sort the list. How do I group the results.??

Use the {% ifchanged %} template tag:
{% for obj in obj_list %}
{% ifchanged %}
<h2>{{ obj.created_on|date }}</h2>
{% endifchanged %}
<div>{{ obj.name }}</div>
{% endfor %}
Another (slightly more complex) option is to use the {% regroup %} tag.

Related

Django - for each field value

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 %}

How to filter objects from template?

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 %}

Double loop with django Templates

so I have this matrix sent to a view
[[6.197, 6.156, 6.165, 6.164, 4.741], [6.191, 6.106, 6.175, 6.132, 4.741], [6.158, 6.137, 6.137, 6.133, 4.741]]
and a list containing dates
["11-12-2016","12-12-2016","13-12-2016"]
and I want to format them with Template to look like this
[["11-12-2016",6.197, 6.156, 6.165, 6.164, 4.741]
["12-12-2016",6.191, 6.106, 6.175, 6.132, 4.741]
....]
Iam using this code :
{% for date in dates %}
{% with forloop.counter0 as i %}
,["{{date}}"{% for item in selling.i %} ,{{item}} {% endfor %}]
{% endwith %}
{% endfor %}
and it doesn't work , but when I replace i with 0,1.. the second loop works fine on one list
{% for item in selling.i %}
This isn't going to work -- the template will look for an attribute or index literally equal to "i", and not the value of that variable.
The Django template language actively discourages using too much logic in the template, and this is an example of something you can't do.
So create the lists as you want them in Python, and pass those to the template. E.g. in Python
combined = [[str(date)] + sell for date, sell in zip(dates, selling)]
And in the template
{% for row in combined %}
[{{ row|join:","|safe }}],
{% endfor %}

Can I reduce queries while iterating a RelatedManager object within a template?

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)

django DateTimeField list records by day

Hay, i have a field in one of my models which saves the creation date of an object
created_on = models.DateTimeField(blank=False, auto_now_add=True)
This works as expected.
In my templates i want to list objects like this
June 15
{{ objects here which was created on June 15 }}
June 14
{{ objects here which was created on June 14 }}
etc
Any idea how i would go about doing this?
Thanks in advance.
First in the view, make sure your objects are ordered by the 'created_on' field.
object_list = MyObjs.objects.all().order_by('created_on')
I believe you should then be able to use the following code in your template:
{% regroup object_list by created_on|date:"Y-m-d" as objects_by_day %}
{% for day in objects_by_day %}
{{day.list.0.created_on|date:"M d"}}
{% for obj in day.list %}
{{obj}}
{% endfor %}
{% endfor %}
This makes use of the regroup template tag, grouping the items by day, creating a list of objects per day. The date itself is output by using the 'date' template filter to reformat the created_on field of the first item in that date's list.
[Note: I have not tested this!]
The place for this is in the template, not the view.
You want the ifchanged template filter, which you use like this:
<h1>Archive for {{ year }}</h1>
{% for entry in entries %}
{% ifchanged %}<h3>{{ entry.date|date:"F" }}</h3>{% endifchanged %}
<p>{{ entry.date|date:"j" }} - {{ entry.title }}</p>
{% endfor %}
In this example, every time the month changes, a heading showing the month will be printed.
ifchanged can do some relatively complex things (e.g. checking if multiple variables have all changed), and can have an optional else block - see the docs for more.
you can for example generate list of dates(by day on given interval) in your view ordered from min to max, and get all objects in this interval. Then create templatetag that takes 2 arguments queryset and date,
and filter records which created(or something else) by your date.