Skip to content

Commit 93e7b13

Browse files
authored
Fix RecursionError for circular self relationships (#343)
1 parent ef73f87 commit 93e7b13

File tree

3 files changed

+25
-1
lines changed

3 files changed

+25
-1
lines changed

rest_framework_filters/filterset.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -217,6 +217,10 @@ def get_param_filter_name(cls, param, rel=None):
217217
if not param:
218218
return param
219219

220+
# check that param is not the rel.
221+
if param == rel:
222+
return None
223+
220224
# strip the rel prefix from the param name.
221225
prefix = '%s%s' % (rel or '', LOOKUP_SEP)
222226
if rel and param.startswith(prefix):

tests/test_filtering.py

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -281,6 +281,16 @@ def test_indirect_recursive_relation(self):
281281
self.assertEqual(c.title, "C1")
282282

283283
def test_direct_recursive_relation(self):
284+
# see: https://github.com/philipn/django-rest-framework-filters/issues/333
285+
GET = {
286+
'best_friend': 1
287+
}
288+
f = PersonFilter(GET, queryset=Person.objects.all())
289+
self.assertEqual(len(list(f.qs)), 1)
290+
p = list(f.qs)[0]
291+
self.assertEqual(p.name, "Mark")
292+
293+
def test_direct_recursive_relation__lookup(self):
284294
GET = {
285295
'best_friend__name__endswith': 'hn'
286296
}

tests/test_filterset.py

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,8 @@
1010
from rest_framework_filters.filterset import FilterSetMetaclass, SubsetDisabledMixin
1111

1212
from .testapp.filters import (
13-
AFilter, NoteFilter, NoteFilterWithAlias, PostFilter, TagFilter, UserFilter,
13+
AFilter, NoteFilter, NoteFilterWithAlias, PersonFilter, PostFilter, TagFilter,
14+
UserFilter,
1415
)
1516
from .testapp.models import Note, Person, Post, Tag, User
1617

@@ -355,6 +356,15 @@ def test_relationship_regular_filter(self):
355356
name = UserFilter.get_param_filter_name('author__email', rel='author')
356357
self.assertEqual('email', name)
357358

359+
def test_recursive_self_filter(self):
360+
name = PersonFilter.get_param_filter_name('best_friend')
361+
self.assertEqual('best_friend', name)
362+
363+
def test_related_recursive_self_filter(self):
364+
# see: https://github.com/philipn/django-rest-framework-filters/issues/333
365+
name = PersonFilter.get_param_filter_name('best_friend', rel='best_friend')
366+
self.assertEqual(None, name)
367+
358368
def test_twice_removed_related_filter(self):
359369
class PostFilterWithDirectAuthor(PostFilter):
360370
note__author = filters.RelatedFilter(UserFilter)

0 commit comments

Comments
 (0)