我有一个与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中排序)。
答案 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位用户阅读的文章。