commit
47042b9498
|
@ -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]+))?
|
||||
|
|
|
@ -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)
|
||||
---------------------------
|
||||
|
|
|
@ -3,7 +3,7 @@ from __future__ import absolute_import
|
|||
from .filterset import FilterSet
|
||||
from .filters import *
|
||||
|
||||
__version__ = '0.15.2'
|
||||
__version__ = '0.15.3'
|
||||
|
||||
|
||||
def parse_version(version):
|
||||
|
|
|
@ -1,4 +1,6 @@
|
|||
|
||||
from __future__ import absolute_import
|
||||
|
||||
import django
|
||||
from django.conf import settings
|
||||
|
||||
|
@ -12,6 +14,13 @@ except ImportError:
|
|||
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
|
||||
|
|
|
@ -89,3 +89,15 @@ class DjangoFilterBackend(BaseFilterBackend):
|
|||
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()
|
||||
]
|
||||
|
|
|
@ -48,9 +48,9 @@ copyright = u'2013, Alex Gaynor and others.'
|
|||
# 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.
|
||||
|
|
|
@ -12,6 +12,8 @@ Meta options
|
|||
- :ref:`order_by <order-by>`
|
||||
- :ref:`form <form>`
|
||||
- :ref:`together <together>`
|
||||
- filter_overrides
|
||||
- :ref:`strict <strict>`
|
||||
|
||||
|
||||
.. _model:
|
||||
|
@ -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:
|
||||
|
@ -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``
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
coreapi
|
||||
|
||||
coverage
|
||||
mock
|
||||
pytz
|
||||
|
|
|
@ -1,3 +1,3 @@
|
|||
-r travis-ci.txt
|
||||
-r test-ci.txt
|
||||
django
|
||||
djangorestframework
|
||||
|
|
2
setup.py
2
setup.py
|
@ -6,7 +6,7 @@ f = open('README.rst')
|
|||
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"):
|
||||
|
|
|
@ -2,6 +2,7 @@ from __future__ import unicode_literals
|
|||
|
||||
import datetime
|
||||
from decimal import Decimal
|
||||
from unittest import skipIf
|
||||
|
||||
from django.conf.urls import url
|
||||
from django.test import TestCase
|
||||
|
@ -17,7 +18,7 @@ except ImportError:
|
|||
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
|
||||
|
||||
|
@ -121,6 +122,35 @@ urlpatterns = [
|
|||
]
|
||||
|
||||
|
||||
@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()}
|
||||
|
|
Loading…
Reference in New Issue