首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >Django按最新评分列出所有作者

Django按最新评分列出所有作者
EN

Stack Overflow用户
提问于 2011-08-08 08:28:21
回答 3查看 360关注 0票数 3

考虑到Django文档中的以下简化模型,我想返回所有作者的列表,这些作者根据他们最近的条目或过去某个日期之前的评级分组。

代码语言:javascript
运行
复制
 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操作大型数据集。有没有人能推荐一个更干净的替代方案?

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2011-08-08 12:41:40

另一种方法

代码语言:javascript
运行
复制
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)

这是你可以做到的一种方法。基本上,您先按最近的条目(在本例中是上周的条目)排序,然后按最旧的条目排序,然后将值列表返回的列表转换为字典。发生的事情是,当它被转换成字典时,新的条目会重创旧的条目,所以你最终会得到一个以作者为关键字,以作者的评分为值的字典。

票数 2
EN

Stack Overflow用户

发布于 2011-08-08 09:13:33

如果没有大量的工作,在vanilla Django中很难做到最近(最大,平均,等等都可以通过注释和聚合来完成)。

我用一个定制的管理器来做这件事,比如:

代码语言:javascript
运行
复制
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模型中:

代码语言:javascript
运行
复制
class Author():
    ...
    objects = AuthorManager()

然后,当您想要具有评分的作者时,您只需查询:

代码语言:javascript
运行
复制
authors = Author.objects.with_recent_rating().filter(...)

除了作者现在有了一个recent_rating字段之外,它实际上和任何其他的fetch一样快。

代码语言:javascript
运行
复制
for author in authors:
    print author.recent_rating
票数 2
EN

Stack Overflow用户

发布于 2011-08-09 16:17:34

实际上,你可以在你的模板中完全做到这一点。像这样的东西应该是有效的:

代码语言:javascript
运行
复制
**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

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/6976792

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档