Django:使用嵌套模型进行查询的复杂排序

Posted

技术标签:

【中文标题】Django:使用嵌套模型进行查询的复杂排序【英文标题】:Django: complex order by query with nested models 【发布时间】: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 日期订购产品,即最接近当前日期。

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

【问题讨论】:

【参考方案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 订购的,所以过滤器在这个查询中不起作用。

以上是关于Django:使用嵌套模型进行查询的复杂排序的主要内容,如果未能解决你的问题,请参考以下文章

Django-使用 ManyToManyField 查询嵌套模型中的重复查询

如何在sequelize中对嵌套模型中的列进行排序?

Django ORM 嵌套模型

在 Django 中进行一个复杂的查询,我所有的后续帖子

Laravel:根据嵌套关系的字段对查询结果进行排序

如何在 django 中进行复杂的搜索?使用视图还是模型?