Skip to content

Commit 589335e

Browse files
carltongibsonsigvef
authored andcommitted
Allowed Q objects in limit_choices_to introspection. (encode#6472)
Closes encode#6470.
1 parent f0e9678 commit 589335e

File tree

3 files changed

+27
-5
lines changed

3 files changed

+27
-5
lines changed

rest_framework/utils/field_mapping.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -251,7 +251,9 @@ def get_relation_kwargs(field_name, relation_info):
251251

252252
limit_choices_to = model_field and model_field.get_limit_choices_to()
253253
if limit_choices_to:
254-
kwargs['queryset'] = kwargs['queryset'].filter(**limit_choices_to)
254+
if not isinstance(limit_choices_to, models.Q):
255+
limit_choices_to = models.Q(**limit_choices_to)
256+
kwargs['queryset'] = kwargs['queryset'].filter(limit_choices_to)
255257

256258
if has_through_model:
257259
kwargs['read_only'] = True

tests/models.py

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,13 @@ class ForeignKeySourceWithLimitedChoices(RESTFrameworkModel):
5959
on_delete=models.CASCADE)
6060

6161

62+
class ForeignKeySourceWithQLimitedChoices(RESTFrameworkModel):
63+
target = models.ForeignKey(ForeignKeyTarget, help_text='Target',
64+
verbose_name='Target',
65+
limit_choices_to=models.Q(name__startswith="limited-"),
66+
on_delete=models.CASCADE)
67+
68+
6269
# Nullable ForeignKey
6370
class NullableForeignKeySource(RESTFrameworkModel):
6471
name = models.CharField(max_length=100)

tests/test_relations_pk.py

Lines changed: 17 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,10 +5,11 @@
55

66
from rest_framework import serializers
77
from tests.models import (
8-
ForeignKeySource, ForeignKeySourceWithLimitedChoices, ForeignKeyTarget,
9-
ManyToManySource, ManyToManyTarget, NullableForeignKeySource,
10-
NullableOneToOneSource, NullableUUIDForeignKeySource, OneToOnePKSource,
11-
OneToOneTarget, UUIDForeignKeyTarget
8+
ForeignKeySource, ForeignKeySourceWithLimitedChoices,
9+
ForeignKeySourceWithQLimitedChoices, ForeignKeyTarget, ManyToManySource,
10+
ManyToManyTarget, NullableForeignKeySource, NullableOneToOneSource,
11+
NullableUUIDForeignKeySource, OneToOnePKSource, OneToOneTarget,
12+
UUIDForeignKeyTarget
1213
)
1314

1415

@@ -378,6 +379,18 @@ def test_queryset_size_with_limited_choices(self):
378379
queryset = ForeignKeySourceWithLimitedChoicesSerializer().fields["target"].get_queryset()
379380
assert len(queryset) == 1
380381

382+
def test_queryset_size_with_Q_limited_choices(self):
383+
limited_target = ForeignKeyTarget(name="limited-target")
384+
limited_target.save()
385+
386+
class QLimitedChoicesSerializer(serializers.ModelSerializer):
387+
class Meta:
388+
model = ForeignKeySourceWithQLimitedChoices
389+
fields = ("id", "target")
390+
391+
queryset = QLimitedChoicesSerializer().fields["target"].get_queryset()
392+
assert len(queryset) == 1
393+
381394

382395
class PKNullableForeignKeyTests(TestCase):
383396
def setUp(self):

0 commit comments

Comments
 (0)