Skip to content

Commit

Permalink
Merge pull request #524 from carltongibson/develop
Browse files Browse the repository at this point in the history
Version 0.15.3
  • Loading branch information
Carlton Gibson authored Oct 17, 2016
2 parents 783940d + eb298ee commit 47042b9
Show file tree
Hide file tree
Showing 11 changed files with 71 additions and 20 deletions.
2 changes: 1 addition & 1 deletion .bumpversion.cfg
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
[bumpversion]
current_version = 0.15.2
current_version = 0.15.3
commit = False
tag = False
parse = (?P<major>\d+)\.(?P<minor>\d+)\.(?P<patch>\d+)(\-(?P<release>[a-z]+))?
Expand Down
8 changes: 8 additions & 0 deletions CHANGES.rst
Original file line number Diff line number Diff line change
@@ -1,3 +1,11 @@
Version 0.15.3 (2016-10-17)
---------------------------

Adds compatibility for DRF (3.5+) get_schema_fields filter backend
introspection.

* #492 Port get_schema_fields from DRF


Version 0.15.2 (2016-09-29)
---------------------------
Expand Down
2 changes: 1 addition & 1 deletion django_filters/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
from .filterset import FilterSet
from .filters import *

__version__ = '0.15.2'
__version__ = '0.15.3'


def parse_version(version):
Expand Down
9 changes: 9 additions & 0 deletions django_filters/compat.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@

from __future__ import absolute_import

import django
from django.conf import settings

Expand All @@ -12,6 +14,13 @@
is_crispy = 'crispy_forms' in settings.INSTALLED_APPS and crispy_forms


# coreapi only compatible with DRF 3.4+
try:
from rest_framework.compat import coreapi
except ImportError:
coreapi = None


def remote_field(field):
"""
https://docs.djangoproject.com/en/1.9/releases/1.9/#field-rel-changes
Expand Down
12 changes: 12 additions & 0 deletions django_filters/rest_framework/backends.py
Original file line number Diff line number Diff line change
Expand Up @@ -89,3 +89,15 @@ def to_html(self, request, queryset, view):
return template_render(template, context={
'filter': filter_instance
})

def get_schema_fields(self, view):
# This is not compatible with widgets where the query param differs from the
# filter's attribute name. Notably, this includes `MultiWidget`, where query
# params will be of the format `<name>_0`, `<name>_1`, etc...
assert compat.coreapi is not None, 'coreapi must be installed to use `get_schema_fields()`'
filter_class = self.get_filter_class(view, view.get_queryset())

return [] if not filter_class else [
compat.coreapi.Field(name=field_name, required=False, location='query')
for field_name in filter_class().filters.keys()
]
4 changes: 2 additions & 2 deletions docs/conf.py
Original file line number Diff line number Diff line change
Expand Up @@ -48,9 +48,9 @@
# built documents.
#
# The short X.Y version.
version = '0.15.2'
version = '0.15.3'
# The full version, including alpha/beta/rc tags.
release = '0.15.2'
release = '0.15.3'

# The language for content autogenerated by Sphinx. Refer to documentation
# for a list of supported languages.
Expand Down
16 changes: 3 additions & 13 deletions docs/ref/filterset.txt
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@ Meta options
- :ref:`order_by <order-by>`
- :ref:`form <form>`
- :ref:`together <together>`
- filter_overrides
- :ref:`strict <strict>`


.. _model:
Expand Down Expand Up @@ -120,7 +122,7 @@ This lets you override the displayed names for your ordering fields::

Note that the default query parameter name used for ordering is ``o``. You
can override this by setting an ``order_by_field`` attribute on the
``FilterSet`` class to the string value you would like to use.
``FilterSet``'s Meta class to the string value you would like to use.


.. _form:
Expand Down Expand Up @@ -152,18 +154,6 @@ field set must either be all or none present in the request for
fields = ['price', 'release_date', 'rating']
together = ['rating', 'price']


Non-Meta options
----------------

Note that these options do not go in the Meta class, they are specified directly
in your FilterSet class.

- filter_overrides
- order_by_field
- :ref:`strict <strict>`


.. _strict:

``strict``
Expand Down
2 changes: 2 additions & 0 deletions requirements/test-ci.txt
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
coreapi

coverage
mock
pytz
2 changes: 1 addition & 1 deletion requirements/test.txt
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
-r travis-ci.txt
-r test-ci.txt
django
djangorestframework
2 changes: 1 addition & 1 deletion setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
readme = f.read()
f.close()

version = '0.15.2'
version = '0.15.3'

if sys.argv[-1] == 'publish':
if os.system("pip freeze | grep wheel"):
Expand Down
32 changes: 31 additions & 1 deletion tests/rest_framework/test_backends.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

import datetime
from decimal import Decimal
from unittest import skipIf

from django.conf.urls import url
from django.test import TestCase
Expand All @@ -17,7 +18,7 @@
from rest_framework import generics, serializers, status
from rest_framework.test import APIRequestFactory

from django_filters import filters
from django_filters import compat, filters
from django_filters.rest_framework import DjangoFilterBackend, FilterSet
from django_filters.rest_framework import backends

Expand Down Expand Up @@ -121,6 +122,35 @@ def get_queryset(self):
]


@skipIf(compat.coreapi is None, 'coreapi must be installed')
class GetSchemaFieldsTests(TestCase):
def test_fields_with_filter_fields_list(self):
backend = DjangoFilterBackend()
fields = backend.get_schema_fields(FilterFieldsRootView())
fields = [f.name for f in fields]

self.assertEqual(fields, ['decimal', 'date'])

def test_fields_with_filter_fields_dict(self):
class DictFilterFieldsRootView(FilterFieldsRootView):
filter_fields = {
'decimal': ['exact', 'lt', 'gt'],
}

backend = DjangoFilterBackend()
fields = backend.get_schema_fields(DictFilterFieldsRootView())
fields = [f.name for f in fields]

self.assertEqual(fields, ['decimal', 'decimal__lt', 'decimal__gt'])

def test_fields_with_filter_class(self):
backend = DjangoFilterBackend()
fields = backend.get_schema_fields(FilterClassRootView())
fields = [f.name for f in fields]

self.assertEqual(fields, ['text', 'decimal', 'date'])


class CommonFilteringTestCase(TestCase):
def _serialize_object(self, obj):
return {'id': obj.id, 'text': obj.text, 'decimal': str(obj.decimal), 'date': obj.date.isoformat()}
Expand Down

0 comments on commit 47042b9

Please sign in to comment.