2👍
Another approach
from collections import defaultdict
from datetime import datetime, timedelta
week_ago = datetime.now() - timedelta(days=7)
author_recent_ratings = dict(Entry.objects.filter(pub_date__gt=week_ago)
.order_by('pub_date')
.select_related()
.values_list('author', 'rating'))
recent_by_rating = defaultdict(list)
for author, rating in author_recent_ratings.iteritems():
recent_by_rating[rating].append(author)
This is one way you could do it. Basically you order by most recent entries (in this case entries from the last week) then order by oldest first, and then you convert the list returned by values list into a dict. What happens is, as it’s converted into a dict and the newer entries clobber the older ones so you end up with a dict that has authors as keys, with their ratings as the values.
2👍
Recent is hard to do in vanilla Django without a lot of work (max, average, etc. can all be done with annotations and aggregations).
I do this with a custom manager something like:
class AuthorManager(models.Manager):
def with_recent_rating(self):
return super(AuthorManager, self).get_query_set().extra(
select={
'recent_rating': '''
SELECT e.rating
FROM myapp_entry e
WHERE e.authors_id = myapp_author.id
ORDER BY e.pub_date DESC
LIMIT 1
''',
})
Then add the following to the Author model:
class Author():
...
objects = AuthorManager()
Then when you want authors with the ratings you just query:
authors = Author.objects.with_recent_rating().filter(...)
It’s practically the same speed as any other fetch except now the authors have a recent_rating field.:
for author in authors:
print author.recent_rating
- [Django]-Django incorporating ads
- [Django]-KeyError at /login/
- [Django]-Django, PostgreSQL, set_autocommit and test cases
- [Django]-Inverted logic in Django ModelForm
1👍
You could actually do this entirely in your template. Something like this should work:
**Views.py**
authors = Author.objects.all()
**Template**
{% regroup authors by rating_set.all|last as rating_list %}
{% for rating in rating_list %}
<b>{{ rating.grouper }}</b><br>
{% for author in rating.list %}
{{ author.name }}<br>
{% endfor %}
{% endfor %}
Basically this method groups all of your authors by rating using the regroup
template tag. The last
filter should give you the most recent rating in the list of each author’s ratings. After that it’s just a basic regroup exercise to break it down by rating and display all the authors for each rating.
https://docs.djangoproject.com/en/dev/ref/templates/builtins/?from=olddocs#regroup
https://docs.djangoproject.com/en/dev/ref/templates/builtins/?from=olddocs#last
- [Django]-Django-mptt filter without breaking the tree
- [Django]-Running manage.py command through Gunicorn
- [Django]-Out of range value adjusted for column warning in django when adding a large integer (11 chars)
- [Django]-Django Custom User Model Best Practice: User = get_user_model()?