Python/Django — what is the difference between the “and” operator and the “&” operator

前端 未结 3 1215
[愿得一人]
[愿得一人] 2021-01-24 00:25

I have a interesting Django problem.

Consider the following:

Model.objects.filter(Q(id=\'test1\') and Q(id=\'test2\'))

this returns the

相关标签:
3条回答
  • 2021-01-24 00:53

    according to the following tutorial

    & is a Binary AND Operator copies a bit to the result if it exists in both operands.

    Example: Assume if a = 60; and b = 13; Now in binary format they will be as follows:

    a = 0011 1100

    b = 0000 1101

    (a & b) will give 12 which is 0000 1100

    and Called Logical AND operator. If both the operands are true then then condition becomes true.

    Example: (a and b) is true.

    So the & was performing binary addition on your query set. Interesting.

    0 讨论(0)
  • 2021-01-24 00:56

    I think you want OR here, and not AND

    filters = ['test1', 'test2', 'test3', 'test4']
    filtered = Model.objects.filter(Q(id = filters[0]))
    for f in filters[1:]:
         subset = Model.objects.filter(Q(id = f))
         filtered = filtered | subset
    
    0 讨论(0)
  • 2021-01-24 01:02

    If you want Django ORM to return test1 and test2, you should use :

    Model.objects.filter(Q(id='test1') | Q(id='test2'))
    

    Model.objects.filter(Q(id='test1') & Q(id='test2')) means return model objects whose id is test1 while its is test2 at the same time. Of course, django will return an empty QuerySet.

    and is a boolean operator in Python. For operation x and y the result is if x is false, then x, else y. Thus Q(id='test1') and Q(id='test2') equals Q(id='test1'), it is not what you want.

    &/| is the the bitwise and/or operator.

    BTW, there's no way to override the boolean operator, but you can override &/| operators in your class by define a method named __and__ / __or__.

    below is the source code of the django Q object[github]:

    class Q(tree.Node):
        """
        Encapsulates filters as objects that can then be combined logically (using
        & and |).
        """
        # Connection types
        AND = 'AND'
        OR = 'OR'
        default = AND
    
        def __or__(self, other):
            return self._combine(other, self.OR)
    
        def __and__(self, other):
            return self._combine(other, self.AND)
        ...
    
    0 讨论(0)
提交回复
热议问题