Django .order_by()与.distinct()使用postgres

时间:2012-06-27 15:43:26

标签: django postgresql

我有一个与Read模型相关的Article模型。我想做的是创建一个查询集,其中文章是唯一的并由date_added排序。由于我使用的是postgres,我更倾向于使用.distinct()方法并指定article字段。像这样:

articles = Read.objects.order_by('article', 'date_added').distinct('article')

但是,这不会产生预期的效果,并按创建顺序对查询集进行排序。我知道Django文档中关于.distinct().order_by()的说明,但我不认为它适用于此处,因为它提到的副作用会有重复,我没有看到

# To actually sort by date added I end up doing this
articles = sorted(articles, key=lambda x: x.date_added, reverse=True)

这在我真正需要之前执行整个查询,如果有大量记录,可能会变得很慢。我已经使用select_related()进行了优化。

是否有更好,更有效的方法来创建具有相关模型和order_by日期唯一性的查询?

更新 理想情况下,输出将是Read实例的查询集,其中它们的相关文章在查询集中是唯一的,并且仅使用Django orm(即在python中排序)。

1 个答案:

答案 0 :(得分:2)

  

是否有更好,更有效的方法来创建具有相关模型和order_by日期唯一性的查询?

Possibily。没有完整的图片很难说,但我的假设是你正在使用Read来跟踪哪些文章已被阅读,哪些文章没有被阅读,并可能将其与User实例联系起来以确定某个特定用户是不是读了一篇文章。如果是这样的话,你的方法是有缺陷的。相反,你应该做类似的事情:

class Article(models.Model):
    ...
    read_by = models.ManyToManyField(User, related_name='read_articles')

然后,要获得特定用户的阅读文章,您可以这样做:

user_instance.read_articles.order_by('date_added')

这需要使用distinct,因为现在不会有任何重复。

<强>更新

获取至少一位用户阅读的所有文章:

Article.objects.filter(read_by__isnull=False)

或者,如果要设置流行度阈值,可以使用注释:

from django.db.models import Count

Article.objects.annotate(read_count=Count('read_by')).filter(read_count__gte=10)

这只会为您提供至少有10位用户阅读的文章。