Разница между использованием 'и' и использованием '&' в Django ORM - PullRequest
0 голосов
/ 13 февраля 2019

У меня есть запрос, который показывает разные результаты, когда я использую и или &

criteria1 = Q(id__gte=802, id__lte=1000)
criteria2 = Q(country_id__contains='UK')

Я всегда использовал:

q = Mymodel.objects.filter(criteria1 & criteria2)

Но в этом конкретном случае, когда я использую & , он всегда выводит одну строку. (я также проверил print q.query () , запрос работает нормально)

Однако, когда я использую и вместо* * & тысяча двадцать-один .Запрос дает правильный вывод

q = Mymodel.objects.filter(criteria1 and criteria2)

что на самом деле происходит под капотом?

Ответы [ 2 ]

0 голосов
/ 13 февраля 2019

Q объект определяет магический метод __or__ и __and__.Эти функции позволяют переопределять операции & math и |.Отметьте этот документ

И если вы хотите узнать о разнице между and и &, см. этот вопрос

Это Q объектный код .Вы можете найти ниже код.

class Q(tree.Node):
    def __or__(self, other):
        return self._combine(other, self.OR)

    def __and__(self, other):
        return self._combine(other, self.AND)
0 голосов
/ 13 февраля 2019

Правильный - criteria1 & criteria2.criteria1 and criteria2 использует стандартную булеву логику Python и будет оцениваться как criteria2, тогда как criteria1 & criteria2 использует перегруженный __and__ метод и создает правильное составное Q объект:

In [1]: from django.db.models import Q                                                                                                                                                                                                                                                                                                                        

In [2]: criteria1 = Q(id__gte=802, id__lte=1000)                                                                                                                                                                                                                                                                                                              

In [3]: criteria2 = Q(country_id__contains='UK')                                                                                                                                                                                                                                                                                                              

In [4]: criteria1 & criteria2                                                                                                                                                                                                                                                                                                                                 
Out[4]: <Q: (AND: ('id__gte', 802), ('id__lte', 1000), ('country_id__contains', 'UK'))>

In [5]: criteria1 and criteria2                                                                                                                                                                                                                                                                                                                               
Out[5]: <Q: (AND: ('country_id__contains', 'UK'))>
...