Skip to content

Commit 15cd1c1

Browse files
author
Ryan P Kilby
authored
Deprecate MethodFilter (#113)
1 parent 050108b commit 15cd1c1

File tree

5 files changed

+72
-57
lines changed

5 files changed

+72
-57
lines changed

rest_framework_filters/filters.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,11 @@ class MethodFilter(Filter):
8484
def __init__(self, *args, **kwargs):
8585
self.action = kwargs.pop('action', '')
8686
super(MethodFilter, self).__init__(*args, **kwargs)
87+
warnings.warn(
88+
'MethodFilter is deprecated and no longer necessary. See: '
89+
'https://github.com/philipn/django-rest-framework-filters/issues/109',
90+
DeprecationWarning, stacklevel=2
91+
)
8792

8893
def resolve_action(self):
8994
"""

tests/test_deprecations.py

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -154,3 +154,19 @@ class Meta:
154154
# Generate another warning for field
155155
F({'id__in': '1'}).qs
156156
self.assertEqual(len(w), 2)
157+
158+
159+
class MethodFilterDeprecationTests(TestCase):
160+
161+
def test_notification(self):
162+
with warnings.catch_warnings(record=True) as w:
163+
warnings.simplefilter("always")
164+
165+
class F(FilterSet):
166+
username__in = filters.MethodFilter()
167+
168+
class Meta:
169+
model = User
170+
fields = []
171+
172+
self.assertEqual(len(w), 1)

tests/test_filterset.py

Lines changed: 0 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,6 @@
22
from __future__ import absolute_import
33
from __future__ import unicode_literals
44

5-
import datetime
6-
75
import django
86
from django.test import TestCase
97

@@ -22,7 +20,6 @@
2220
NoteFilterWithRelatedAll,
2321
NoteFilterWithRelatedAllDifferentFilterName,
2422
PostFilter,
25-
CoverFilterWithRelatedMethodFilter,
2623
CoverFilterWithRelated,
2724
# PageFilterWithRelated,
2825
TagFilter,
@@ -556,44 +553,6 @@ def test_non_filter_subset(self):
556553
self.assertEqual(len(filterset_class.base_filters), 0)
557554

558555

559-
class MethodFilterTests(TestCase):
560-
561-
@classmethod
562-
def setUpTestData(cls):
563-
user = User.objects.create(username="user1", email="user1@example.org")
564-
565-
note1 = Note.objects.create(title="Test 1", content="Test content 1", author=user)
566-
note2 = Note.objects.create(title="Test 2", content="Test content 2", author=user)
567-
568-
post1 = Post.objects.create(note=note1, content="Test content in post 1")
569-
post2 = Post.objects.create(note=note2, content="Test content in post 2", date_published=datetime.date.today())
570-
571-
Cover.objects.create(post=post1, comment="Cover 1")
572-
Cover.objects.create(post=post2, comment="Cover 2")
573-
574-
def test_method_filter(self):
575-
GET = {
576-
'is_published': 'true'
577-
}
578-
filterset = PostFilter(GET, queryset=Post.objects.all())
579-
results = list(filterset.qs)
580-
self.assertEqual(len(results), 1)
581-
self.assertEqual(results[0].content, "Test content in post 2")
582-
583-
def test_related_method_filter(self):
584-
"""
585-
Missing MethodFilter filter methods are silently ignored, returning
586-
the unfiltered queryset.
587-
"""
588-
GET = {
589-
'post__is_published': 'true'
590-
}
591-
filterset = CoverFilterWithRelatedMethodFilter(GET, queryset=Cover.objects.all())
592-
results = list(filterset.qs)
593-
self.assertEqual(len(results), 1)
594-
self.assertEqual(results[0].comment, "Cover 2")
595-
596-
597556
class FilterOverrideTests(TestCase):
598557

599558
def test_declared_filters(self):

tests/test_regressions.py

Lines changed: 44 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,14 +19,16 @@
1919
from rest_framework.renderers import JSONRenderer
2020

2121
from .testapp.models import (
22-
User, Person,
22+
User, Person, Note, Post, Cover,
2323
)
2424

2525
from .testapp.filters import (
2626
UserFilter,
2727
AllLookupsPersonDateFilter,
2828
InSetLookupPersonIDFilter,
2929
InSetLookupPersonNameFilter,
30+
PostFilter,
31+
CoverFilterWithRelatedMethodFilter,
3032
)
3133

3234

@@ -284,3 +286,44 @@ def test_isnull_override(self):
284286
results = list(filterset.qs)
285287
self.assertEqual(len(results), 1)
286288
self.assertEqual(results[0].username, 'user2')
289+
290+
291+
class FilterMethodTests(TestCase):
292+
"""
293+
Old test case for MethodFilter. Ensure that the new Filter.method remains compatible.
294+
"""
295+
296+
@classmethod
297+
def setUpTestData(cls):
298+
user = User.objects.create(username="user1", email="user1@example.org")
299+
300+
note1 = Note.objects.create(title="Test 1", content="Test content 1", author=user)
301+
note2 = Note.objects.create(title="Test 2", content="Test content 2", author=user)
302+
303+
post1 = Post.objects.create(note=note1, content="Test content in post 1")
304+
post2 = Post.objects.create(note=note2, content="Test content in post 2", date_published=datetime.date.today())
305+
306+
Cover.objects.create(post=post1, comment="Cover 1")
307+
Cover.objects.create(post=post2, comment="Cover 2")
308+
309+
def test_method_filter(self):
310+
GET = {
311+
'is_published': 'true'
312+
}
313+
filterset = PostFilter(GET, queryset=Post.objects.all())
314+
results = list(filterset.qs)
315+
self.assertEqual(len(results), 1)
316+
self.assertEqual(results[0].content, "Test content in post 2")
317+
318+
def test_related_method_filter(self):
319+
"""
320+
Missing MethodFilter filter methods are silently ignored, returning
321+
the unfiltered queryset.
322+
"""
323+
GET = {
324+
'post__is_published': 'true'
325+
}
326+
filterset = CoverFilterWithRelatedMethodFilter(GET, queryset=Cover.objects.all())
327+
results = list(filterset.qs)
328+
self.assertEqual(len(results), 1)
329+
self.assertEqual(results[0].comment, "Cover 2")

tests/testapp/filters.py

Lines changed: 7 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -68,31 +68,23 @@ class Meta:
6868

6969

7070
class PostFilter(FilterSet):
71-
# Used for Related filter and MethodFilter tests
71+
# Used for Related filter and Filter.method regression tests
7272
note = RelatedFilter(NoteFilterWithRelatedAll, name='note')
7373
date_published = filters.AllLookupsFilter()
74-
is_published = filters.MethodFilter()
74+
is_published = filters.BooleanFilter(name='date_published', method='filter_is_published')
7575

7676
class Meta:
7777
model = Post
7878

79-
def filter_is_published(self, name, qs, value):
79+
def filter_is_published(self, qs, name, value):
8080
"""
8181
`is_published` is based on the actual `date_published`.
8282
If the publishing date is null, then the post is not published.
8383
"""
84-
# convert value to boolean
85-
null = value.lower() != 'true'
86-
87-
# The lookup name will end with `is_published`, but could be
88-
# preceded by a related lookup path.
89-
if LOOKUP_SEP in name:
90-
rel, _ = name.rsplit(LOOKUP_SEP, 1)
91-
name = LOOKUP_SEP.join([rel, 'date_published__isnull'])
92-
else:
93-
name = 'date_published__isnull'
94-
95-
return qs.filter(**{name: null})
84+
isnull = not value
85+
lookup_expr = LOOKUP_SEP.join([name, 'isnull'])
86+
87+
return qs.filter(**{lookup_expr: isnull})
9688

9789

9890
class CoverFilterWithRelatedMethodFilter(FilterSet):

0 commit comments

Comments
 (0)