如何在模型上进行 Django 查询,其中我按字段 A 排序,但在字段 B 上进行不同的过滤?



>假设我有一个 Book 表,其中每本书都有一个作者字段和一个出版日期字段。

我想得到每个作者的最新书。我正在使用PostgreSQL作为后端。

明显(和错误(的解决方案是:

Book.objects.order_by("author", "-published_on").distinct("author").all()

问题在于,虽然结果只包含每个作者的一本书,但不能保证它是最新的书。这可能是因为我使用随机 UUID 作为 PK。我无法改变这一点。这是一个要求。

下一个明显(也是错误的(解决方案是:

Book.objects.order_by("author", "-published_on").distinct("author", "published_on").all()

在这里,书籍的顺序是正确的,但我们从同一作者那里得到了多本书。

我也尝试翻转参数:

Book.objects.order_by("-published_on", "author").distinct("published_on", "author").all()

在这里,书籍的顺序是正确的,但我们从同一作者那里得到了多本书。

如何进行 Django ORM 查询,从每个作者那里获得最新书籍?

编辑:这是我实际上在我们的实时数据库上运行的一个查询,然后将其转换为书籍样式的示例:

from db.models import User, EventVisibility
user = User.objects.get(username="7g8jltdzbz46ak7nhuz8tzfuu7y9mdym7tiy7klfxjnn")
evs = EventVisibility.objects.filter(user=user).order_by("room", "-created_on").distinct("room")[:20]
for ev in evs:
print(f"book_id={ev.room.room_id}, published_on={ev.created_on}")

这些是结果:

book_id=2mcnhajfwf5jsgyzpqix36ytbjfucn9u6derkyurlfff, published_on=2020-05-16 00:54:05.083477+00:00
book_id=4rp9ffxqr5marnphbtlahqtwnkzozupyb8ht532ffxl6, published_on=2020-05-12 20:29:31.286095+00:00
book_id=5dqygkksrzq6ay49xxcspagma5cbz8p59sjcavf6pepm, published_on=2020-05-08 09:28:53.508563+00:00
book_id=9mz85qcxreaczcnenebcywqqm3scehjhpwlkso7g4jbd, published_on=2020-05-04 10:52:06.396995+00:00
book_id=9sgiiasbvbtat4iahx7bd7ammzwatgfipe8wmzl9snz5, published_on=2020-05-15 09:00:52.602512+00:00
book_id=b8uvcxuhgjhmvkjjnwkcr5zzj7hrushz2e9mpzkosg8k, published_on=2020-05-08 09:36:47.148885+00:00
book_id=bxif8aal2v4fb3p8wsdvdard5p65ygw8j92tnleqqza4, published_on=2020-04-19 02:43:23.819854+00:00
book_id=cgoad7xuwjhxz6hcxctbl5arnnsrjt5osuwmzunmppra, published_on=2020-05-08 09:36:06.944614+00:00
book_id=cztb84akqqde6fvpj2nneqezvmor5gdjh3hpcjnxcz2x, published_on=2020-05-15 10:06:53.054862+00:00
book_id=czxizxptbvxz7jybkxevk2mkmaxykhgakfluud7ffa2b, published_on=2020-05-17 14:54:43.245325+00:00
book_id=dgtze2ri5snrr7nmurvdechydxjd2ph3dd8rugibn2me, published_on=2020-05-05 19:16:45.254928+00:00
book_id=dp9wu8qmdw6prsvx2zwvrnw5akcxv6llcwa2skeadcpx, published_on=2020-04-27 10:58:32.555542+00:00
book_id=duelfazwfiek8jhr4ew7wa9vrzzuyhznzxcrpybmbuww, published_on=2020-05-15 10:06:45.001961+00:00
book_id=dwhqxqfyolggdf5wwwm3su3yq6ffsh5kwwjxj7wtkdbj, published_on=2020-05-15 05:53:01.153492+00:00
book_id=edakxxhqv7w99lukxr23dfugcarddpwj5ea8wx7r5bmd, published_on=2020-04-27 19:49:29.673872+00:00
book_id=evz9biehu88eds7hgcutw6jfktt4fkjznfgozxsu8jtk, published_on=2020-04-20 21:13:01.693752+00:00
book_id=fqnxa3j4vbbaw7fc5hgrumabtfh2phmd3hg7cgm5ayfa, published_on=2020-05-15 10:04:22.322094+00:00
book_id=gkxahh8y7eqtqzxsnjtdpnghxnipi8vx3qugjcrs6t3m, published_on=2020-04-17 02:14:31.219950+00:00
book_id=hdgoxpnmqde8siwdbgfwwtodqk4hzhefyz8pw3esdmem, published_on=2020-05-17 14:46:49.437289+00:00
book_id=jrg6uae5kyvfvjgjhmwvzf45lbtqmgspawbuqzfewnhc, published_on=2020-05-05 09:11:59.334099+00:00

这是queryset.query

SELECT DISTINCT ON ("db_eventvisibility"."room_id") "db_eventvisibility"."id", "db_eventvisibility"."event_id", "db_eventvisibility"."user_id", "db_eventvisibility"."room_id", "db_eventvisibility"."unit_id", "db_eventvisibility"."case_id", "db_eventvisibility"."team_id", "db_eventvisibility"."created_on" FROM "db_eventvisibility" WHERE "db_eventvisibility"."user_id" = 7g8jltdzbz46ak7nhuz8tzfuu7y9mdym7tiy7klfxjnn ORDER BY "db_eventvisibility"."room_id" ASC, "db_eventvisibility"."created_on" DESC LIMIT 20

问题是,虽然结果只包含每个作者的一本书,但不能保证它是最新的书。这可能是因为我使用随机 UUID 作为 PK。我无法改变这一点。这是一个要求。

据我所知,结果是正确的,因为根据Room,您确实会得到最新的EventVisibility,但这可能不是您想要的。如果要按最新EventVisibilityRoom进行排序,则可以使用以下方法执行此操作:

from django.db.models import Max
Room.objects.filter(
eventvisibility__user=user
).order_by(
Max('eventvisibitility__created_on').desc()
)

最新更新