[Django]-Neutral element for "|" and "&" operations for django.db.models.Q objects?

7đź‘Ť

âś…

I finally found the solution, which was in fact pretty simple… the “neutral element” for Q objects, which is the same for operations “|” and “&” is: “Q()”

I now have a dynamic filter which can match everything I want in my templates…

# Models
class MyModel(models.Model):
    myfield1 = models.CharField(max_length=30)
    myfield2 = models.CharField(max_length=30)
    myinteger3 = models.IntegerField(blank=True, null=True)



# Views
class MyView(views.View):
    model = MyModel

    def get_queryset(self):
        def myfunc(query_object_list, param):
            myfuncr = lambda l: ((myfuncr(l[1:]) | Q(**{ param: l[0] })) if l else Q()) # Q() is the neutral element of operation "|" for Q objects
            return myfuncr(query_object_list)

        myq = Q() # Q() is the neutral element of operation "&" for Q objects
        for param in self.request.GET:
            myq &= myfunc(self.request.GET.getlist(param, None), param)

        return MyModel.objects.filter(myq)


# Template
<a href='{% url myview %}?myfield1__iexact={{ myvar1 }}&myfield2__iexact={{ myvar2 }}&myinteger3__gte={{ myvar3 }}'>foobar</a>

<a href='{% url myview %}?myinteger3__gte={{ myvar4 }}'>{{ myvar4 }}</a>
👤gueux

2đź‘Ť

Who cares.

myq = reduce(operator.and_, (myfunc(self.request.GET.getlist(param, None), param) for param in self.request.GET))

0đź‘Ť

I don’t really understand what you’re trying to do, but I don’t think the question actually makes sense in this context. & and | are not really boolean operators on Q objects: the code overrrides the __and__ and __or__ methods so that they combine their arguments into a tree, which is how Django represents queries internally before converting to SQL.

Leave a comment