<p>好的,主要的问题似乎是您有元组和列表,而不是<code>Q</code>对象。例如,该行</p>
<pre><code>q_list = (Q(is_private=False), Q(is_active=True))
</code></pre>
<p>将与以下选项中的任一选项一样正确:</p>
<pre><code>q_obj = Q(Q(is_private=False), Q(is_active=True))
q_obj = Q(is_private=False, is_active=True)
</code></pre>
<hr/>
<p>但也许你的整个方法可以稍加修改</p>
<pre><code>def get_containers(customer_id=None, course_id=None):
customer_q = Q()
org_q = Q()
if customer_id:
# this may raise Customer.DoesNotExist error
customer = Customer.objects.get(id=customer_id)
# Top level restriction: restricted to org
org_q = Q(restrictions__organisation=customer.org.id)
# Second level restriction: may have a customer-id
customer_q = Q(
Q(restrictions__customer__isnull=True)
| Q(restrictions__customer=customer.id))
course_q = Q()
if course_id:
# Third level restriction: may be restricted to a course-code
course_q = Q(
Q(restrictions__course_code__isnull=True)
| Q(restrictions__course_code=course_id))
# apply Q to queryset
return Container.objects.filter(
Q(is_private=False, is_active=True) & org_q & customer_q & course_q)
</code></pre>
<p>我建议您创建空的<code>Q</code>对象,并仅在满足条件时替换它们(例如,仅当<code>course_id</code>为true时);如果不满足这些条件,那么它只是保持一个空的<code>Q</code>对象,这意味着一个空的filter子句。这样<code>.filter()</code>调用就更容易编码了</p>