4

During django websie development I came across of django Q objects & query.

I have below code like.

I have referred official documentation from https://docs.djangoproject.com/en/2.2/topics/db/queries/.

 query = Q()
    if request.POST.get('emp_name') != None:
        query.add(Q(emp_name__icontains=str(request.POST.get('emp_name'))), query.connector)

I know how Query Q objects works but not able to understand how query.connector value defined.

query.connector value will be like 'AND' , 'OR' likewise.

I am not able to get any online references for above kind of problem.

1 Answer 1

3

Short answer: If you do not pass a _connector yourself. Django will end up using 'AND' as a connector.

A Q object is a subclass of tree.Node. Indeed we can inspect the source code [GitHub]:

class Q(tree.Node):
    """
    Encapsulate filters as objects that can then be combined logically (using
    `&` and `|`).
    """
    # Connection types
    AND = 'AND'
    OR = 'OR'
    default = AND
    conditional = True

    def __init__(self, *args, _connector=None, _negated=False, **kwargs):
        super().__init__(children=[*args, *sorted(kwargs.items())], connector=_connector, negated=_negated)

    # …

When we thus construct a Q object, we make a super call to the tree.Node data constructor, and if we do not pass a _connector, it will take None as value.

The Node itself will however take the default in case the truthiness of the connector is None. Indeed, if we look at the source code of Node [GitHub], we see:

class Node:
    """
    A single internal node in the tree graph. A Node should be viewed as a
    connection (the root) with the children being either leaf nodes or other
    Node instances.
    """
    # Standard connector type. Clients usually won't use this at all and
    # subclasses will usually override the value.
    default = 'DEFAULT'

    def __init__(self, children=None, connector=None, negated=False):
        """Construct a new Node. If no connector is given, use the default."""
        self.children = children[:] if children else []
        self.connector = connector or self.default
        self.negated = negated

    # …

This thus means that if you construct a Q object, the default connector is the value of Q.AND and thus 'AND'.

Sign up to request clarification or add additional context in comments.

1 Comment

I got it. Superb !

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.