I have a database query for some items (containers
).
There is a related table that could define some restrictions (Only those in a top-level org
, only those in a dept
(customer) in an org
, or just those in a team
(course) in a dept
)
Here's my (not working) code to get the list of objects:
def get_containers(customer_id: None, course_id: None):
q_list = (Q(is_private=False), Q(is_active=True))
if customer_id:
try:
customers = Customer.objects
customer = customers.get(id=customer_id)
except KeyError:
return None
# Second level restriction: may have a customer-id
customer_q = (
Q(restrictions__customer__isnull=True)
| Q(restrictions__customer=customer.id)
)
# Third level restriction: may be restricted to a course-code
course_q = Q(restrictions__course_code__isnull=True)
if course_id:
course_q |= Q(restrictions__course_code=course_id)
# Top level restriction: restricted to org
restrictions_q = (
Q(restrictions__organisation=customer.org.id)
& customer_q
& course_q
)
q_list = (Q(q_list) | Q(restrictions_q))
print(f"q_list: {q_list}")
return Container.objects.filter(q_list)
I've been using https://docs.djangoproject.com/en/3.0/topics/db/queries/#complex-lookups-with-q (& the referenced https://github.com/django/django/blob/master/tests/or_lookups/tests.py), and the previously asked django dynamically filtering with q objects as references during this.
I've tried a bunch of variations to get the OR
at the end of the if customer_id:
block to work - and they all give me errors:
q_list = q_list | restrictions_q\nTypeError: unsupported operand type(s) for |: 'tuple' and 'Q'
q_list = Q(q_list | restrictions_q)\nTypeError: unsupported operand type(s) for |: 'tuple' and 'Q'
q_list |= restrictions_q\nTypeError: unsupported operand type(s) for |=: 'tuple' and 'Q'
q_list.add(restrictions_q, Q.OR)\nAttributeError: 'tuple' object has no attribute 'add'
Question: How to I create the q_list = q_list OR restrictions_q
construct?