考虑到Django文档中的以下简化模型,我想返回所有作者的列表,这些作者根据他们最近的条目或过去某个日期之前的评级分组。
class Author(models.Model):
name = models.CharField(max_length=50)
email = models.EmailField()
class Entry(models.Model):
headline = models.CharField(max_length=255)
pub_date = models.DateTimeField()
mod_date = models.DateTimeField()
authors = models.ForeignKey(Author)
rating = models.IntegerField()最后,我想把它变成一个python字典,比如:{1star:(author1,author2),2star:(author3,author4,author5)...}。
一种想法是返回所有条目,然后使用itertools.groupby操作大型数据集。有没有人能推荐一个更干净的替代方案?
发布于 2011-08-08 12:41:40
另一种方法
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)这是你可以做到的一种方法。基本上,您先按最近的条目(在本例中是上周的条目)排序,然后按最旧的条目排序,然后将值列表返回的列表转换为字典。发生的事情是,当它被转换成字典时,新的条目会重创旧的条目,所以你最终会得到一个以作者为关键字,以作者的评分为值的字典。
发布于 2011-08-08 09:13:33
如果没有大量的工作,在vanilla Django中很难做到最近(最大,平均,等等都可以通过注释和聚合来完成)。
我用一个定制的管理器来做这件事,比如:
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
''',
})然后将以下内容添加到Author模型中:
class Author():
...
objects = AuthorManager()然后,当您想要具有评分的作者时,您只需查询:
authors = Author.objects.with_recent_rating().filter(...)除了作者现在有了一个recent_rating字段之外,它实际上和任何其他的fetch一样快。
for author in authors:
print author.recent_rating发布于 2011-08-09 16:17:34
实际上,你可以在你的模板中完全做到这一点。像这样的东西应该是有效的:
**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 %}基本上,此方法使用regroup模板标记按评级对所有作者进行分组。last过滤器应该会在每个作者的评分列表中为您提供最新的评分。在那之后,这只是一个基本的重组练习,通过评级将其分解,并显示每个评级的所有作者。
https://docs.djangoproject.com/en/dev/ref/templates/builtins/?from=olddocs#regroup
https://docs.djangoproject.com/en/dev/ref/templates/builtins/?from=olddocs#last
https://stackoverflow.com/questions/6976792
复制相似问题