Skip to content

Instantly share code, notes, and snippets.

@dpetzel
Last active November 28, 2019 09:28
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save dpetzel/d039fff0baf3f8e1639a to your computer and use it in GitHub Desktop.
Save dpetzel/d039fff0baf3f8e1639a to your computer and use it in GitHub Desktop.
drf_filtering_boolean_ignorecase

myapp/lib/filters.py

from django.forms.widgets import NullBooleanSelect
from django.db import models
from django import forms

from django_filters.filters import BooleanFilter
from django_filters.filterset import FilterSet

from rest_framework.filters import DjangoFilterBackend

class NullBooleanSelectFixed(NullBooleanSelect):
    def value_from_datadict(self, data, files, name):
        value = data.get(name, None)
        if value in (True, 'True', 'true', '1'):
            return True
        elif value in (False, 'False', 'false', '0'):
            return False
        else:
            return None

class NullBooleanFieldFixed(forms.NullBooleanField):
    widget = NullBooleanSelectFixed

class BooleanFilterFixed(BooleanFilter):
    field_class = NullBooleanFieldFixed

class SmarterFilterSet(FilterSet):
    filter_overrides = dict(FilterSet.filter_overrides,
        **{models.BooleanField: {'filter_class': BooleanFilterFixed}})

class SmarterDjangoFilterBackend(DjangoFilterBackend):
    """
    An extension of the DjangoFilterBackend that properly handles boolean types

    https://groups.google.com/forum/#!topic/django-filter/vbTttMhqH0I
    """
    default_filter_set = SmarterFilterSet

settings.py

REST_FRAMEWORK = {
    'DEFAULT_FILTER_BACKENDS': (
        'myapp.lib.filter.SmarterDjangoFilterBackend',
        # 'rest_framework.filters.DjangoFilterBackend'
    ),
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment