django 查询所有与相关集的过滤?

Posted

技术标签:

【中文标题】django 查询所有与相关集的过滤?【英文标题】:django query all with filtering on the related set? 【发布时间】:2018-09-22 08:12:04 【问题描述】:
class Customer(models.Model):
  name = models.CharField(max_length=200)
  # ..


class CustomerTicket(models.Model):
  customer = models.OneToOneField(Customer)
  date = models.DateTimeField(auto_now_add=True)
  # ..

我想查询所有客户。并且,如果在日期范围内有一张票,则为每个客户添加它的票 - 所以只有当票对象在给定的日期范围内时,我才会获取票对象,否则票字段将为空。

【问题讨论】:

你想要有票的顾客吗? 不,我想要所有这些,将票证添加为计算字段,可能为空 【参考方案1】:

试试这个:

from django.db import models

customers = Customer.objects.select_related('customerticket').annotate(
    ticket=models.Case(models.When(models.Q(customerticket__date__gt=date1) & models.Q(customerticket__date__lt=date2), then=models.F('customerticket')))
)

您将获得ticket 作为计算域。请注意,在引用 ForeignKey 或 OneToOneField 等关系字段时,F() 返回主键值而不是模型实例,这意味着您的 ticket 字段将具有主键值。

【讨论】:

我不知道为什么,但是输出非常大,有很多重复的行 重复行是什么意思? 我多次获得同一个客户 如果你运行Customer.objects.all(),你会得到重复吗? 我没有。 annotate 不是要用于 group by 语句吗?【参考方案2】:

要通过一次查询获得相关票证的客户,您可以使用select_related。要制作复杂的条件,您可以使用Q

from django.db.models import Q    
Customer.objects.select_related('customerticket').filter(Q(customerticket__date__range=["2018-04-11", "2018-04-12"]) | Q(customerticket__isnull=True))

这将按客户出票日期过滤数据。

【讨论】:

忘了说,我还需要按日期字段过滤。编辑了问题 试过这种方式,它不会查询所有的客户,这个查询强制客户有一张票。我要查询所有客户,所以过滤条件应该是only在相关字段上 @user3599803 只需添加or 条件,查看我的更新。 它只在日期范围内给我,而不是所有客户,所以isnull 条件似乎不起作用【参考方案3】:

使用 queryset.filter:

from django.utils import timezone

Customer.objects.exclude(customerticket=None).filter(customerticket__date=timezone.now())

【讨论】:

与上述答案相同的问题 编辑了我的答案

以上是关于django 查询所有与相关集的过滤?的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 Django 中另一个查询集的结果过滤查询集?

模板中的 Django 动态对象过滤问题

有没有办法检查字符串是不是是 django 查询集的有效过滤器?

Django 查询集的过滤内置条件

具有过滤查询集的组权限的自定义表单

django相关查询过滤器,搜索有无相关项目的项目