gpt4 book ai didi

django - 使用过滤连接中的最新值注释 QuerySet

转载 作者:行者123 更新时间:2023-12-04 18:02:17 26 4
gpt4 key购买 nike

如何在单个表达式中从多对一关系的过滤结果中获取最新值以注释 Django QuerySet?

给定这个玩具模式:

from django.db import models

class Lorem(models.Model):
""" Lorem ipsum, dolor sit amet. """

class LoremStatusEvent(models.Model):
""" A status event change on a given `ipsum` for a `lorem`. """

created = models.DateTimeField(auto_now_add=True)
lorem = models.ForeignKey(Lorem)
ipsum = models.CharField(max_length=200)
status = models.CharField(max_length=10)

为了在 Django 中创建自定义 QuerySet LoremAdmin (对于 Lorem 模型),我需要:
  • 派生 foo_statusbar_status每个从单独的 JOIN 子句到 LoremStatusEvent型号:lorem.loremstatusevent_set__status .
  • 过滤每个连接以仅包含那些用于相应 Ipsum 的事件值:foo_status_events=LoremStatusEvent.filter(ipsum='foo') .
  • 将状态事件集聚合为每个对应连接的最新状态事件:foo_status=LoremStatusEvent.objects.filter(ipsum='foo').latest('created').status .
  • 用几个额外的值注释结果,foo_statusbar_status : queryset = queryset.annotate(foo_status=???).annotate(bar_status=???) .

  • 如果我发明了一些函数来完成这一切—— get_field , latest_by , filter_by , loremstatus_set_of_every_corresponding_lorem – 我可以这样写管理员:

    from django.contrib import admin

    class LoremAdmin(admin.ModelAdmin):
    """ Django admin for `Lorem` model. """

    class Meta:
    model = Lorem

    def get_queryset(request):
    """ Get the `QuerySet` of all instances available to this admin. """
    queryset = super().get_queryset(request)
    queryset.annotate(
    foo_status=(
    get_field('status')(
    latest_by('created')(
    filter_by(ipsum='foo')(
    loremstatusevent_set_of_every_corresponding_lorem)))),
    bar_status=(
    get_field('status')(
    latest_by('created')(
    filter_by(ipsum='bar')(
    loremstatusevent_set_of_every_corresponding_lorem)))),
    )
    return queryset

    哪些实际函数应该替换这些占位符名称?
  • loremstatus_set_of_every_corresponding_lorem , 相当于 Lorem.loremstatusevent_set .
  • filter_by , 过滤右侧的连接。
  • latest_by ,聚合结果集,按字段排序,获取单个最新实例。我没有看到任何这样的documented aggregation function .
  • get_field , 从结果实例中引用一个字段。

  • 请记住,所有这些都需要在 Lorem 的查询集上完成。实例,通过 Lorem.loremstatusevent_set访问相关实例;我没有 LoremStatusEvent那个时候的实例,所以我不能直接使用 LoremStatusEvent 的属性.

    那么,上述占位符中应该包含哪些实际的 Django 功能?

    最佳答案

    您应该可以使用新的 Subquery 来做到这一点。功能,也可作为 backport to 1.8+ .

    try:
    from django.db.models.expressions import Subquery, OuterRef
    except ImportError:
    from django_subquery.expressions import Subquery, OuterRef

    class LoremAdmin(admin.ModelAdmin):
    # …

    def get_queryset(request):
    queryset = super().get_queryset(request)
    status_event_per_lorem = LoremStatusEvent.objects.filter(
    lorem=OuterRef('pk'))
    latest_status_event_per_lorem = (
    status_event_per_lorem.order_by(
    'pk', '-created').distinct('pk'))
    latest_status_event_for_ipsum_foo = (
    latest_status_event_per_lorem.filter(ipsum='foo'))
    latest_status_event_for_ipsum_bar = (
    latest_status_event_per_lorem.filter(ipsum='bar'))
    queryset = queryset.annotate(
    foo_status=Subquery(
    latest_status_event_for_ipsum_foo.values('status')[:1]),
    bar_status=Subquery(
    latest_status_event_for_ipsum_bar.values('status')[:1]),
    )

    return queryset

    关于django - 使用过滤连接中的最新值注释 QuerySet,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43775102/

    26 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com