3

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

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

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

# 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 日期唯一性的查询?

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

4

1 回答 1

2

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

可能。没有全貌很难说,但我的假设是您正在使用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 位用户阅读过的文章。

于 2012-06-27T16:19:34.590 回答