[英]Django Query, distinct on foreign key
鑒於這些模型
class User(Model):
pass
class Post(Model):
by = ForeignKey(User)
posted_on = models.DateTimeField(auto_now=True)
我想獲得最新的Post
,但不是全部來自同一個User
,我有這樣的事情:
posts = Post.objects.filter(public=True) \
.order_by('posted_on') \
.distinct("by")
但是 distinct 在 mysql 上不起作用,我想知道是否有另一種方法可以做到? 我已經看到一些使用values()
,但values
對我不起作用,因為我需要對對象本身做更多的事情
order_by
應該匹配distinct()
。 在你的情況下,你應該這樣做:
posts = Post.objects.filter(public=True) \
.order_by('by') \
.distinct('by')
.distinct([*fields])
僅適用於 PostgresSQL。
對於 MySql 引擎。 這是 Django 中的MySQL
文檔:
這就是不同之處。 對於普通的 distinct() 調用,數據庫在確定哪些行不同時比較每行中的每個字段。 對於具有指定字段名稱的 distinct() 調用,數據庫將僅比較指定的字段名稱。
對於 MySql 解決方法可能是這樣的:
from django.db.models import Subquery, OuterRef
user_post = Post.objects.filter(user_id=OuterRef('id')).order_by('posted_on')
post_ids = User.objects.filter(related_posts__isnull=False).annotate(post=Subquery(user_post.values_list('id', flat=True)[:1]))).values_list('post', flat=True)
posts = Post.objects.filter(id__in=post_ids)
由於 distinct 不能在其他字段上與 MySQL 一起使用,然后是模型id
,因此使用Subquery可以解決此問題:
from django.db.models import Subquery, OuterRef
...
sub_qs = Post.objects.filter(user_id=OuterRef('id')).order_by('posted_on')
# here you get users with annotated last post
qs = User.objects.annotate(last_post=Subquery(sub_qs[:1]))
# next you can limit the number of users
另請注意,對posted_on
字段的排序取決於您的模型約束 - 也許您需要將其更改為-posted_on
以從最新的頂部排序。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.