I am building a Blog App and I made a queryset
which is showing blog date and likes
of every day since blog date
, But it is showing in dictionary
and i am trying to show both instances differently in table like.
Blog Date | Likes |
---|---|
20 Sep. | 6 Likes |
21 Sep. | 2 Likes |
22 Sep. | 4 Likes |
But it is showing like :-
({20: 6},{21: 2},{22: 4})
models.py
class BlogPost(models.Model):
user = models.ForeignKey(User, on_delete=models.CASCADE)
title = models.CharField(max_length=30, default='')
date = models.DateTimeField(auto_now_add=True)
class Likes(models.Model):
user = models.ForeignKey(User, on_delete=models.CASCADE)
blogpost_like = models.ForeignKey(BlogPost, on_delete=models.CASCADE)
views.py
from django.db.models.functions import ExtractDay
from collections import Counter
def page(request):
blogpost = get_object_or_404(BlogPost,pk=pk)
totals = blogpost.likes_set.filter(
blogpost_like__date=blogpost.date,
).annotate(
date=ExtractDay('blogpost__date'),
).values(
'date'
).annotate(
n=Count('pk')
).order_by('date').values()
results = Counter({d['date']: d['n'] for d in totals})
context = {'results':results}
return render(request, 'page.html', context)
What have i tried ? :-
- I have tried
lists = [{'id': blog.date, 'name': blog.n} for blog in results ]
But it is showing only date like 24
not the likes.
- than i tried
json.dumps(list(results ))
- than i tried
from calendar import monthrange
__, ds = monthrange(blogpost.date)
finalSecond = [data[i] for i in range(1, ds 1)]
But it showed
monthrange() missing 1 required positional argument: 'month'
I have tried many times but it is still not working.
Any help would be much Appreciated. Thank You
CodePudding user response:
{d['date']: d['n'] for d in totals}
Makes a dict whose keys are the date and whose vals are the value. Whilst the data can be extracted from this, it doesn't make any sense, particularly as you store them in a list. But you already have nicely structured output in your totals, so use that directly without wrapping it all up in a Counter
of dicts (I have no idea why you are using Counter
, by the way).
return render(request, 'page.html', {"results": totals})
That way your data is getting through to the template nicely. Then your html template just needs to iterate over results:
{% for result in results %}
<tr>
<td>result.date</td><td>result.n</td>
</tr>
{% endfor %}
CodePudding user response:
You can use TruncDate
to obtain the date:
from django.db.models import Count
from django.db.models.functions import TruncDate
totals = blogpost.likes_set.filter(
blogpost__date=blogpost.date,
).values(
date=TruncDate('blogpost__date')
).annotate(
n=Count('pk')
).order_by('date')
If you pass this to the context, you can render it with:
<table>
<thead>
<th>Blog Date</th><th>Likes</th>
</thead>
<tbody>
{% for item in totals %}
<tr>
<td>{{ item.date|date:"F, d" }}</td><td>{{ item.n }}</td>
</tr>
{% endfor %}
</tbody>
</table>