1

我正在处理会员申请。我想做一个会员提醒。(在一段时间内成为成员,在另一时间段内不是成员)。

目前,我正在使用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)

我想知道我只能通过使用 django ORM(过滤器、排除、注释、不同......)来做到这一点?

在此先感谢您的帮助

更新

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

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)

我想要给定报纸的提醒。在这种情况下,工作查询是

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)

我认为这是 Ghislain Leveque 给出的答案的更详细版本,这对我来说也很有效。

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

4

3 回答 3

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))

请注意,对于简单的 anding 和基本查找,您不需要 Q 对象,就像我在前两个查找参数中展示的那样。Anding 仅通过传递多个参数发生,需要 Q 对象来进行否定和 OR'ing 查找。

于 2010-08-02T09:53:03.083 回答
3

关系数据库表一个集合——根据定义。Set-where not existsSQL 中,exclude在 Django 的 ORM 中。

似乎(未经测试)您正在这样做。

result = Member.objects.filter(
    Q(membership__start_date__lte=dt1) & Q(membership__end_date__gte=dt1)
).exclude(
    Q(membership__start_date__lte=dt2) & Q(membership__end_date__gte=dt2)
)
于 2010-08-02T10:14:09.567 回答
1

你应该试试 :

result = Member.objects.\
    filter(
        membership__start_date__lte = dt1,
        membership__end_date__gte=dt1).\
    exclude(
        pk__in = \
            Member.objects.filter(
                membership__start_date__lte = dt2,
                membership__end_date__gte = dt2).\
    values_list('pk')
于 2010-08-02T09:55:45.027 回答