Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Use Custom Filter with Django ModelChoice Filter

I am trying to create use the filter method with django-filters

See an example of the models below:

class Chicken(TimeStampedModel):
    eggs = ForeignKey(Egg)

class Egg(TimeStampedModel):
    hatched = BooleanField(default=False)

See an example of my current set up for the filter:

class ChickenFilter(FilterSet):
    eggs__contains = ModelChoiceFilter(name="eggs", method='hatched_eggs', queryset=Eggs.objects.all())

   def hatched_eggs(self, queryset, name, value):
      print "We got eggs"
     return queryset.filter(eggs__hatched=True)

The problem is that the method doesnt even print We got eggs when I hit the url. It just returns an empty queryset.

like image 883
Crystal Avatar asked Mar 24 '17 21:03

Crystal


People also ask

Can you filter by property Django?

Django-property-filter is an extension to django-filter and provides functionality to filter querysets by class properties. It does so by providing sub-classes for Filters and Filtersets to keep existing django-filter functionality. For more details and examples check the documentation.

How do I filter Queryset in Django REST framework?

The simplest way to filter the queryset of any view that subclasses GenericAPIView is to override the . get_queryset() method. Overriding this method allows you to customize the queryset returned by the view in a number of different ways.

How do you use MultipleChoiceFilter?

MultipleChoiceFilter. The same as ChoiceFilter except the user can select multiple choices and the filter will form the OR of these choices by default to match items. The filter will form the AND of the selected choices when the conjoined=True argument is passed to this class.


2 Answers

I did it like below:

In my urls I sent ?ids=1,2,3,4

class MyFilter(filters.FilterSet):
    ids = django_filters.CharFilter(method='ids__in')

    def ids__in(self, queryset, value, *args, **kwargs):
        try:
            if args:
                ids = args[0].split(',')
                ids = [int(_id) for _id in ids]
                queryset = queryset.filter(id__in=ids)
        except ValueError:
            pass
        return queryset
like image 163
Fred Chevitarese Avatar answered Nov 08 '22 07:11

Fred Chevitarese


I was going through the same problem. My method was not being called.

So came to conclusion, I can make a workaround using:

Using custom methods in filter with django-rest-framework

class ChickenFilter(FilterSet):
    eggs__contains = CharFilter(action='hatched_eggs')

def hatched_eggs(queryset, value):
      print "We got eggs"
     if value:
         return queryset.filter(eggs__hatched=True)
     return queryset
like image 4
AnnShress Avatar answered Nov 08 '22 08:11

AnnShress