Skip to content

Commit

Permalink
Copy DjangoFilterBackend from DRF
Browse files Browse the repository at this point in the history
  • Loading branch information
Ryan P Kilby committed Sep 4, 2016
1 parent 18040df commit b3f23ef
Show file tree
Hide file tree
Showing 8 changed files with 515 additions and 0 deletions.
7 changes: 7 additions & 0 deletions django_filters/compat.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,13 @@
import django


# django-crispy-forms is optional
try:
import crispy_forms
except ImportError:
crispy_forms = None


def remote_field(field):
"""
https://docs.djangoproject.com/en/1.9/releases/1.9/#field-rel-changes
Expand Down
1 change: 1 addition & 0 deletions django_filters/rest_framework/__init__.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
# flake8: noqa
from __future__ import absolute_import
from .backends import DjangoFilterBackend
from .filterset import FilterSet
from ..filters import *
95 changes: 95 additions & 0 deletions django_filters/rest_framework/backends.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@

from __future__ import absolute_import

from django.conf import settings
from django.template import loader
from django.utils.translation import ugettext_lazy as _

from rest_framework import compat
from rest_framework.filters import BaseFilterBackend

from ..compat import crispy_forms
from . import filterset


if 'crispy_forms' in settings.INSTALLED_APPS and crispy_forms:
from crispy_forms.helper import FormHelper
from crispy_forms.layout import Layout, Submit

class FilterSet(filterset.FilterSet):
def __init__(self, *args, **kwargs):
super(FilterSet, self).__init__(*args, **kwargs)
for field in self.form.fields.values():
field.help_text = None

layout_components = list(self.form.fields.keys()) + [
Submit('', _('Submit'), css_class='btn-default'),
]

helper = FormHelper()
helper.form_method = 'GET'
helper.template_pack = 'bootstrap3'
helper.layout = Layout(*layout_components)

self.form.helper = helper

filter_template = 'django_filters/rest_framework/crispy_form.html'

else:
class FilterSet(filterset.FilterSet):
def __init__(self, *args, **kwargs):
super(FilterSet, self).__init__(*args, **kwargs)
for field in self.form.fields.values():
field.help_text = None

filter_template = 'django_filters/rest_framework/form.html'


class DjangoFilterBackend(BaseFilterBackend):
default_filter_set = FilterSet
template = filter_template

def get_filter_class(self, view, queryset=None):
"""
Return the django-filters `FilterSet` used to filter the queryset.
"""
filter_class = getattr(view, 'filter_class', None)
filter_fields = getattr(view, 'filter_fields', None)

if filter_class:
filter_model = filter_class.Meta.model

assert issubclass(queryset.model, filter_model), \
'FilterSet model %s does not match queryset model %s' % \
(filter_model, queryset.model)

return filter_class

if filter_fields:
class AutoFilterSet(self.default_filter_set):
class Meta:
model = queryset.model
fields = filter_fields

return AutoFilterSet

return None

def filter_queryset(self, request, queryset, view):
filter_class = self.get_filter_class(view, queryset)

if filter_class:
return filter_class(request.query_params, queryset=queryset).qs

return queryset

def to_html(self, request, queryset, view):
filter_class = self.get_filter_class(view, queryset)
if not filter_class:
return None
filter_instance = filter_class(request.query_params, queryset=queryset)
context = {
'filter': filter_instance
}
template = loader.get_template(self.template)
return compat.template_render(template, context)
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{% load crispy_forms_tags %}
{% load i18n %}

<h2>{% trans "Field filters" %}</h2>
{% crispy filter.form %}
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
{% load i18n %}
<h2>{% trans "Field filters" %}</h2>
<form class="form" action="" method="get">
{{ filter.form.as_p }}
<button type="submit" class="btn btn-primary">{% trans "Submit" %}</button>
</form>
28 changes: 28 additions & 0 deletions tests/rest_framework/models.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@

from django.db import models
from django.utils.translation import ugettext_lazy as _


class BasicModel(models.Model):
text = models.CharField(
max_length=100,
verbose_name=_("Text comes here"),
help_text=_("Text description.")
)


class BaseFilterableItem(models.Model):
text = models.CharField(max_length=100)


class FilterableItem(BaseFilterableItem):
decimal = models.DecimalField(max_digits=4, decimal_places=2)
date = models.DateField()


class DjangoFilterOrderingModel(models.Model):
date = models.DateField()
text = models.CharField(max_length=10)

class Meta:
ordering = ['-date']
Loading

0 comments on commit b3f23ef

Please sign in to comment.