Django - 使用'排除'查询多对多关系

时间:2015-07-16 13:21:38

标签: python django django-models

我有两个以多对多关系加入的模型:

class Room(models.Model):
    id = models.CharField(max_length=50, primary_key=True)
    name = models.CharField(max_length=50)

class Event(models.Model):
    id = models.CharField(max_length=50, primary_key=True)
    start = models.DateTimeField()
    end = models.DateTimeField()
    room = models.ManyToManyField(Room)

我试图排除所有会议室在特定日期之前开始并在不同日期之后结束的会议室。我可以使用过滤器获得符合此标准的所有房间:

Room.objects.filter(event__start__lt=date1, event__end__gt=date2)

并且工作正常,但它会返回我想要的所有房间,而不是那些我不想要的房间。但是,如果我做同样的事情,请将filter替换为exclude

Room.objects.exclude(event__start__lte=date1, event__end__gte=date2)

然后它排除了比使用过滤器发现的更多房间。有人知道为什么吗?我目前不得不做一些愚蠢的解决方法,即:

badRooms = Room.objects.filter(event__start__lt=date1, event__end__gt=date2)
badRooms = [x.id for x in badRooms]
return Room.objects.filter(id__in=badRooms)

但这既愚蠢又低效,所以如果有人知道我对exclude做错了什么,那将非常感激!

我认为问题在于多对多关系,因为我需要移除所有至少有一个符合两个条件的单个事件的房间,而不是具有两个不同事件的房间,每个房间都符合其中一个标准。

1 个答案:

答案 0 :(得分:0)

活动有房间,但房间没有活动

尝试:

Event.objects.filter(Q(start__lt=date1) | Q(end__gt=date2))

或:

Event.objects.filter(start__lt=date1, end__gt=date2)

如果您想要结束/启动您必须添加到模型中的房间:

class Room(models.Model):
  id = models.CharField(max_length=50, primary_key=True)
  name = models.CharField(max_length=50)
  start = models.DateTimeField()
  end = models.DateTimeField()

然后你可以像这样过滤:

Event.objects.filter(Q(room__start__lt=date1) | Q(room__end__gt=date2))

或:

Event.objects.filter(room__start__lt=date1, room__end__gt=date2)