Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Django model queryset filter as a function

I'm trying to create a custom function that I can place in a queryset "chain" that will apply a filter to the queryset. Like with normal Django queryset filters, it will take the queryset to the left of it and pass the resulting queryset to the right.

Before adding my custom function to the queryset chain:

models.MyModel.objects.all()
models.MyModel.objects.some_manger_function()
models.MyModel.objects.some_manger_function().count()
models.MyModel.objects.some_manger_function().filter(title='something')

After adding my custom function to the queryset chain:

models.MyModel.objects.all().my_custom_filter()
models.MyModel.objects.some_manger_function().my_custom_filter()
models.MyModel.objects.some_manger_function().my_custom_filter().count()
models.MyModel.objects.some_manger_function().my_custom_filter()\
   .filter(title='something')

I'm not sure how to construct my function to do this. Does it need some sort of decorator around it?

???? def my_custom_filter(???):
????    return qs.filter(id__gte=10)  

Does anyone know a good way to accomplish this?

The following might work, but I was hoping for something a little more Django-like.

def my_custom_filter(qs):
    return qs.filter(id__gte=1)

my_custom_filter(models.MyModel.objects.all()).count()

Any advice is much appreciated.

Thanks, Joe

UPDATE: I'm trying to work out the details of Ignacio's solution. I've not done too much with QuerySet overriding so I'm piecing together what I'm able to find...

class MyQuerySet(QuerySet):

    def filter(self, *args, **kwargs):
        return super(self.__class__, self).filter(*args, **kwargs).\
                     filter(id__gt=5)


class MyManager(models.Manager):

    def testqs(self):
        return MyQuerySet(self.model)

However, I don't think this is working the way I expect. Any suggestions?

>>> models.MyModel.objects.testqs().filter()

UPDATE 2: This article proved to be useful. http://zmsmith.com/2010/04/using-custom-django-querysets/

like image 920
Joe J Avatar asked Feb 08 '11 22:02

Joe J


People also ask

Can I filter a QuerySet Django?

With the Django QuerySet class, you can apply filters that return QuerySets defined by your filters. The filter() method returns all objects that match the keyword arguments given to the method.

What is the purpose of filter () method in Django?

The filter() method is used to filter you search, and allows you to return only the rows that matches the search term.


1 Answers

You will need to write your own QuerySet child class with the method added, then use that class in the manager.

like image 158
Ignacio Vazquez-Abrams Avatar answered Oct 15 '22 23:10

Ignacio Vazquez-Abrams