Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Equality of Django's Q objects

I am trying to compare django's Q objects which are composed in the exact same way.

But despite all children and relations between them being same, they aren't deemed equal.

from django.db.models import Q

$ q1 = Q(a=1) & Q(b=1) & Q(c=1)

$ q2 = Q(a=1) & Q(b=1) & Q(c=1)

$ q1 == q2

$ False

This is posing problems in my unit tests where I build up filters for my querysets using Q objects.

Why are the two Q objects not equal?

I am using Django 1.11.

like image 803
xssChauhan Avatar asked Aug 31 '25 22:08

xssChauhan


1 Answers

Django <= 1.11.x does not implement __eq__ method for Q objects. As can be seen here.

Django >= 2.0 implements __eq__ method for Q objects. Code.

So it is not possible to directly check the equality of two Q objects before Django 2.0.

But it is possible to write a simple function that checks the equality of Q objects. We can directly use the code from the repo.

def compare_q(q1 , q2):
        return (
            q1.__class__ == q2.__class__ and
            (q1.connector, q1.negated) == (q2.connector, q2.negated) and
            q1.children == q2.children
        )

So, for older versions of Django we can do:

$ compare_q(q1 , q2)

$ True
like image 129
xssChauhan Avatar answered Sep 04 '25 03:09

xssChauhan