Skip to content

Instantly share code, notes, and snippets.

@dbrgn
Created May 21, 2015 09:25
Show Gist options
  • Select an option

  • Save dbrgn/581bfab371b9ef25cc4e to your computer and use it in GitHub Desktop.

Select an option

Save dbrgn/581bfab371b9ef25cc4e to your computer and use it in GitHub Desktop.
# -*- coding: utf-8 -*-
from __future__ import print_function, division, absolute_import, unicode_literals
import re
from itertools import izip
import six
from rest_framework.filters import DjangoFilterBackend
from rest_framework.compat import django_filters
class CamelCaseDjangoFilterBackend(DjangoFilterBackend):
"""
Like the DjangoFilterBackend, but with automatic camelCase to under_scores
conversion.
"""
def get_filter_class(self, view, queryset=None):
"""
Return the django-filters `FilterSet` used to filter the queryset.
In case the ``filter_fields`` attribute is being used, all under_scores
are automatically converted to camelCase.
"""
filter_fields = getattr(view, 'filter_fields', None)
if filter_fields:
# Do the conversion
underscore_fields = filter_fields
camel_fields = map(self._camelize, filter_fields)
class DynamicFilterSetMetaclass(django_filters.filterset.FilterSetMetaclass):
"""
Metaclass that dynamically inserts filter definitions to translate
from camelCase to under_scores.
"""
def __new__(cls, name, bases, attrs):
# Add filter attributes where necessary
for underscore, camel in izip(underscore_fields, camel_fields):
if underscore != camel:
attrs[camel] = django_filters.CharFilter(name=underscore)
# Continue with the object creation
return super(DynamicFilterSetMetaclass, cls).__new__(cls, name, bases, attrs)
CamelFilterset = six.with_metaclass(DynamicFilterSetMetaclass, self.default_filter_set)
# Create the FilterSet
class AutoFilterSet(CamelFilterset):
class Meta:
model = queryset.model
fields = camel_fields
return AutoFilterSet
return super(CamelCaseDjangoFilterBackend, self).get_filter_class(view, queryset)
def _camelize(self, value):
"""
Convert the value from under_scores to camelCase.
"""
def underscore_to_camel(match):
return match.group()[0] + match.group()[2].upper()
return re.sub(r'[a-z]_[a-z]', underscore_to_camel, value)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment