【问题标题】:Django: complex order by query with nested modelsDjango:使用嵌套模型进行查询的复杂排序
【发布时间】:2021-07-17 16:08:42
【问题描述】:

我有以下 3 个模型

from django.db.models import Max
from django.utils import timezone


class Product(models.Model):

    name = models.CharField(
    blank=False,
    max_length=256
    )


class TaskGroup(models.Model):
    name = models.CharField(
    blank=False,
    max_length=256
    )

    product = models.ForeignKey(
    Product,
    on_delete=models.CASCADE,
    null=False,
    blank=True
    )


class Task(models.Model):
    name = models.CharField(
    blank=False,
    max_length=256
    )

    task_group = models.ForeignKey(
    TaskGroup,
    on_delete=models.CASCADE,
    null=False,
    blank=True
    )
    
    execute_at = models.DateField(
    blank=True
    null=True,
    )

我可以按任务execute_at日期订购产品。

Products.objects.annotate(
    last_task=Max('taskgroup__task__execute_at')
).order_by('-last_task')

但是,我只需要考虑大于今天的第一个日期,即我需要类似

Products.objects.annotate(
    last_task=('taskgroup__task__execute_at' >= timezone.now()).first()
).order_by('last_task')

所以我需要按最近的 Task execute_at 日期订购产品,即最接近当前日期。

我该怎么做?最好在单个查询中完成。

【问题讨论】:

    标签: django foreign-keys sql-order-by django-queryset


    【解决方案1】:

    由于 DJANGO 2.0 我们可以使用filter argument 来实现这一点。

    下面的行必须做你想做的:

    from django.db.models import Min, Q
    
    Products.objects.annotate(
        last_task=Min(
            'taskgroup__task__execute_at',
            filter=Q(taskgroup__task__execute_at__gte=timezone.now()
    ))).order_by('last_task')
    

    【讨论】:

    • 我不需要过滤产品,我需要通过任务execute_at date where execute_at date is >= timezone.now()来订购产品
    • @StaticName,首先你必须过滤execute_at__gte=timezone.now()。然后你可以用order_by("taskgroup__task__execute_at") 升序或order_by("taskgroup__task__execute_at") 降序。
    • @zelenyjan,我认为他需要第一项,来自问题:我只需要考虑大于今天的第一个日期
    • @StaticName,如果你不需要过滤简单的排除它并且只使用....order_by("-taskgroup__task__execute_at").first()。但要获得大于或等于 timezone.now() 的项目,您必须执行 filter().
    • 即使你做了过滤器,它也不起作用。因为最终产品是由taskgroup__task__execute_at 订购的,所以过滤器在这个查询中不起作用。
    猜你喜欢
    • 2019-01-05
    • 2021-09-28
    • 2021-06-08
    • 1970-01-01
    • 2021-02-02
    • 2022-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多