我完全被这种行为所迷惑。我清楚地不理解我认为我所做过的Q对象,或者我正在做一些非常愚蠢和明显的事情。这是我遇到的问题。 accepted_attendee_ *与OfficialProfile都是m2m关系。在django shell中,为了便于演示。Django Q对象和m2m查询
>>> profile = OfficialProfile.objects.get(user__username='testofficial3')
>>> r = SchedulerEvent.objects.filter(accepted_attendee_referee=profile)
>>> l = SchedulerEvent.objects.filter(accepted_attendee_linesman=profile)
>>> o = SchedulerEvent.objects.filter(accepted_attendee_official=profile)
>>> r
[<SchedulerEvent: andrew>]
>>> l
[]
>>> o
[]
这一切都如预期。现在,如果我将Q对象组合在一起,事情会变得很奇怪。
>>> qevents = SchedulerEvent.objects.filter(Q(accepted_attendee_referee=profile)|Q(accepted_attendee_official=profile)|Q(accepted_attendee_linesman=profile))
>>> qevents
[<SchedulerEvent: andrew>, <SchedulerEvent: andrew>]
两个对象返回,都用相同的PK - 两个重复的对象。应该只有一个,基于个人查询。但是再一次,当我这样做:
>>> r|l|o
[<SchedulerEvent: andrew>, <SchedulerEvent: andrew>]
这是关于这个或查询返回两个对象时应该有,我相信很清楚,只有一个?
编辑
所以,我看着那个被产生的查询,它似乎像“答案”没有任何关系符合Q对象或在的OR'ing所有;相反,这是ORM加入表格的方式。这里的SQL和它产生的结果,如果缺少OR:
mysql> SELECT `scheduler_schedulerevent`.`id`, `scheduler_schedulerevent`.`user_id`, `scheduler_schedulerevent`.`title`, `scheduler_schedulerevent`.`description`, `scheduler_schedulerevent`.`start`, `scheduler_schedulerevent`.`end`, `scheduler_schedulerevent`.`location_id`, `scheduler_schedulerevent`.`age_level_id`, `scheduler_schedulerevent`.`skill_level_id`, `scheduler_schedulerevent`.`officiating_system_id`, `scheduler_schedulerevent`.`auto_schedule`, `scheduler_schedulerevent`.`is_scheduled`
FROM `scheduler_schedulerevent`
LEFT OUTER JOIN `scheduler_schedulerevent_accepted_attendee_referee`
ON (`scheduler_schedulerevent`.`id` = `scheduler_schedulerevent_accepted_attendee_referee`.`schedulerevent_id`)
LEFT OUTER JOIN `scheduler_schedulerevent_accepted_attendee_linesman`
ON (`scheduler_schedulerevent`.`id` = `scheduler_schedulerevent_accepted_attendee_linesman`.`schedulerevent_id`)
LEFT OUTER JOIN `scheduler_schedulerevent_accepted_attendee_official`
ON (`scheduler_schedulerevent`.`id` = `scheduler_schedulerevent_accepted_attendee_official`.`schedulerevent_id`);
+----+---------+---------------+-------------+---------------------+---------------------+-------------+--------------+----------------+-----------------------+---------------+--------------+
| id | user_id | title | description | start | end | location_id | age_level_id | skill_level_id | officiating_system_id | auto_schedule | is_scheduled |
+----+---------+---------------+-------------+---------------------+---------------------+-------------+--------------+----------------+-----------------------+---------------+--------------+
| 1 | 1 | Test Event | | 2015-04-09 02:00:00 | 2015-04-09 02:30:00 | 161 | 1 | 1 | 3 | 0 | 0 |
| 2 | 1 | Test | | 2015-04-07 20:00:00 | 2015-04-07 21:00:00 | 161 | 1 | 1 | 3 | 1 | 0 |
| 3 | 1 | Test Auto | | 2015-04-07 20:00:00 | 2015-04-07 20:30:00 | 161 | 1 | 1 | 2 | 0 | 0 |
| 4 | 1 | Test Official | | 2015-04-16 19:00:00 | 2015-04-16 20:30:00 | 161 | 1 | 1 | 3 | 0 | 1 |
| 4 | 1 | Test Official | | 2015-04-16 19:00:00 | 2015-04-16 20:30:00 | 161 | 1 | 1 | 3 | 0 | 1 |
+----+---------+---------------+-------------+---------------------+---------------------+-------------+--------------+----------------+-----------------------+---------------+--------------+
,然后清楚,当你添加一个OR,它的基础上的连接的结果符合两项查询条件。所以虽然增加不同的查询似乎不必要的,这是非常必要的。
我知道我可以用不同的,但是,这并不回答关于如何以及为什么对象符合两项quesysets的问题。它基本上是相同的查询,结合或子句。如果>>> r.count()+ l.count()+ o.count()等于1,heck可以如何>>> qevents.count()等于2?说真的,我是不是很厚? – ghiotion