From 5a98c8f4c7bdefa541c8b762fbb71f9dc581f029 Mon Sep 17 00:00:00 2001 From: Ryan P Kilby Date: Wed, 19 Oct 2016 13:07:30 -0400 Subject: [PATCH 1/5] Fix all lookups handling for related fields (#128) --- rest_framework_filters/filterset.py | 3 ++- tests/test_filterset.py | 11 +++++++++++ 2 files changed, 13 insertions(+), 1 deletion(-) diff --git a/rest_framework_filters/filterset.py b/rest_framework_filters/filterset.py index 840a748..a237601 100644 --- a/rest_framework_filters/filterset.py +++ b/rest_framework_filters/filterset.py @@ -9,6 +9,7 @@ from django.utils import six from django_filters import filterset, rest_framework +from django_filters.utils import get_model_field from . import filters from . import utils @@ -139,7 +140,7 @@ def filters_for_model(cls, model, opts): lookups = '__all__' if lookups == '__all__': - field = model._meta.get_field(name) + field = get_model_field(model, name) fields[name] = utils.lookups_for_field(field) return filterset.filters_for_model( diff --git a/tests/test_filterset.py b/tests/test_filterset.py index a03078b..944dd5b 100644 --- a/tests/test_filterset.py +++ b/tests/test_filterset.py @@ -63,6 +63,17 @@ class Meta: self.assertIsInstance(F.base_filters['author'], filters.ModelChoiceFilter) self.assertIsInstance(F.base_filters['author__in'], BaseInFilter) + def test_alllookupsfilter_for_related_field(self): + # See: https://github.com/philipn/django-rest-framework-filters/issues/127 + class F(FilterSet): + author = filters.AllLookupsFilter(name='author__last_name') + + class Meta: + model = Note + + self.assertIsInstance(F.base_filters['author'], filters.CharFilter) + self.assertEqual(F.base_filters['author'].name, 'author__last_name') + def test_relatedfilter_combined_with__all__(self): # ensure that related filter is compatible with __all__ lookups. class F(FilterSet): From 33f49ddd469551daa26375d30c713526148b9513 Mon Sep 17 00:00:00 2001 From: Ryan P Kilby Date: Wed, 19 Oct 2016 13:44:43 -0400 Subject: [PATCH 2/5] Fix backend template rendering (#129) * Update to_html --- rest_framework_filters/backends.py | 13 ++++++++----- tests/test_backends.py | 28 +++++++++++++++++++++++++++- 2 files changed, 35 insertions(+), 6 deletions(-) diff --git a/rest_framework_filters/backends.py b/rest_framework_filters/backends.py index 1206458..05edbaa 100644 --- a/rest_framework_filters/backends.py +++ b/rest_framework_filters/backends.py @@ -1,5 +1,5 @@ -from django.template import loader +from django.template import Template, TemplateDoesNotExist, loader from rest_framework import compat from django_filters.rest_framework import backends @@ -28,8 +28,11 @@ def to_html(self, request, queryset, view): # forces `form` evaluation before `qs` is called. This prevents an empty form from being cached. filter_instance.form - context = { + try: + template = loader.get_template(self.template) + except TemplateDoesNotExist: + template = Template(backends.template_default) + + return compat.template_render(template, context={ 'filter': filter_instance - } - template = loader.get_template(self.template) - return compat.template_render(template, context) + }) diff --git a/tests/test_backends.py b/tests/test_backends.py index 4af4426..0e2e315 100644 --- a/tests/test_backends.py +++ b/tests/test_backends.py @@ -1,8 +1,10 @@ -from rest_framework.test import APITestCase +from rest_framework.test import APITestCase, APIRequestFactory from .testapp import models, views +factory = APIRequestFactory() + class BackendTest(APITestCase): @@ -33,3 +35,27 @@ def test_filter_fields_reusability(self): self.assertEqual(len(response.data), 1) self.assertEqual(response.data[0]['username'], 'user1') self.assertDictEqual(views.FilterFieldsUserViewSet.filter_fields, {'username': '__all__'}) + + def test_backend_output_sanity(self): + """ + Sanity check to ensure backend can at least render something without crashing. + """ + class SimpleViewSet(views.FilterFieldsUserViewSet): + filter_fields = ['username'] + + view = SimpleViewSet(action_map={}) + backend = view.filter_backends[0] + request = view.initialize_request(factory.get('/')) + html = backend().to_html(request, view.get_queryset(), view) + + self.assertHTMLEqual(html, """ +

Field filters

+
+

+ + + Filter +

+ +
+ """) From 248a64710fae13462d4a8e1f7bfe78ac2bca6116 Mon Sep 17 00:00:00 2001 From: Ryan P Kilby Date: Tue, 15 Nov 2016 21:06:21 -0500 Subject: [PATCH 3/5] Update changelog w/ 0.9.1 changes --- CHANGELOG.rst | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/CHANGELOG.rst b/CHANGELOG.rst index a73eedc..2ac64c4 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -1,6 +1,12 @@ Unreleased: ----------- +v0.9.1: +------- + +* #128 Fix all lookups handling for related fields +* #129 Fix backend template rendering + v0.9.0: ------- From c802b305edddb40e8d45ba539c3ca84d522d07d9 Mon Sep 17 00:00:00 2001 From: Ryan P Kilby Date: Fri, 18 Nov 2016 17:07:40 -0500 Subject: [PATCH 4/5] Version lock 0.9.x to django-filter<1.0 (#148) --- setup.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/setup.py b/setup.py index 27e96c5..d1ba4b1 100644 --- a/setup.py +++ b/setup.py @@ -43,7 +43,7 @@ def get_package_data(package): zip_safe=False, install_requires=[ 'djangorestframework', - 'django-filter>=0.15.0', + 'django-filter>=0.15.0,<1.0', ], classifiers=[ 'Development Status :: 5 - Production/Stable', From 39baeb28d2687cdf739345f8bcc4e1286bfc9f49 Mon Sep 17 00:00:00 2001 From: Philip Neustrom Date: Sat, 19 Nov 2016 16:45:59 -0500 Subject: [PATCH 5/5] v0.9.1 --- setup.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/setup.py b/setup.py index d1ba4b1..87cc052 100644 --- a/setup.py +++ b/setup.py @@ -32,7 +32,7 @@ def get_package_data(package): setup( name='djangorestframework-filters', - version='0.9.0', + version='0.9.1', url='http://github.com/philipn/django-rest-framework-filters', license='MIT', description='Better filtering for Django REST Framework', pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy