簡體   English   中英

Django 查詢,外鍵不同

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM