如何用django ORM模仿Python集?

luc*_*luc 1 python django django-orm

我正在申请会员申请.我想提出会员提醒.(成员在一段时间内不是另一段时间的成员).

目前,我正在使用set这个计算.请参阅下面的代码.

class Member(models.Model):
     ...

class Membership(models.Model):
    member = models.ForeignKey(Member, verbose_name=_("Member"))
    start_date = models.DateField(_("Start date"))
    end_date = models.DateField(_("End date"))

x = Member.objects.filter(Q(membership__start_date__lte=dt1) & Q(membership__end_date__gte=dt1))
y = Member.objects.filter(Q(membership__start_date__lte=dt2) & Q(membership__end_date__gte=dt2))
result = set(x) - set(y)
Run Code Online (Sandbox Code Playgroud)

我想知道我只能通过使用django ORM(filter,exclude,annotate,distinct ...)来做到这一点?

在此先感谢您的帮助

UPDATE

事实上,我的模型有点复杂.我也有报纸外键.

class Member(models.Model):
     ...

class Newspaper(models.Model):
     ...

class Membership(models.Model):
    member = models.ForeignKey(Member, verbose_name=_("Member"))
    start_date = models.DateField(_("Start date"))
    end_date = models.DateField(_("End date"))
    newspaper = models.ForeignKey(Newspaper)
Run Code Online (Sandbox Code Playgroud)

我希望得到一份特定报纸的提醒.在这种情况下,工作查询是

sin = models.Membership.objects.filter(start_date__lte=dt1,
                                               end_date__gte=dt1,
                                               newspaper__id=2)

sout = models.Membership.objects.filter(start_date__lte=dt2,
                                          end_date__gte=dt2,
                                          newspaper__id=2)
result = models.Member.objects.filter(membership__in=sin).exclude(membership__in=sout)
Run Code Online (Sandbox Code Playgroud)

我认为这是一个更详细的答案给出了Ghislain Leveque,这对我来说也很好.

感谢S.Lott和KillianDS提供了非常有价值的答案,并对不太清楚的问题抱歉:)

Kil*_*nDS 6

是不是简单地否定了第二个表达式并将其放在同一个过滤器中?所以你有类似的东西!(a&b),等于(!a)|(!b),在这种情况下:

result = Member.objects.filter(membership__start_date__lte=dt1, membership__end_date__gte=dt1, ~Q(membership__start_date__lte=dt2) | ~Q(membership__end_date__gte=dt2))
Run Code Online (Sandbox Code Playgroud)

请注意,对于简单的anding和基本查找,您不需要Q对象,就像我使用前两个查找参数一样.Anding只是通过传递多个参数来实现,需要Q对象来否定和OR'ing查找.