diff --git a/rest_framework/utils/field_mapping.py b/rest_framework/utils/field_mapping.py index d3044ff59d..991f20f17a 100644 --- a/rest_framework/utils/field_mapping.py +++ b/rest_framework/utils/field_mapping.py @@ -249,6 +249,10 @@ def get_relation_kwargs(field_name, relation_info): if to_field: kwargs['to_field'] = to_field + limit_choices_to = model_field and model_field.get_limit_choices_to() + if limit_choices_to: + kwargs['queryset'] = kwargs['queryset'].filter(**limit_choices_to) + if has_through_model: kwargs['read_only'] = True kwargs.pop('queryset', None) diff --git a/tests/models.py b/tests/models.py index 6aeceb9345..55f250e046 100644 --- a/tests/models.py +++ b/tests/models.py @@ -52,6 +52,13 @@ class ForeignKeySource(RESTFrameworkModel): on_delete=models.CASCADE) +class ForeignKeySourceWithLimitedChoices(RESTFrameworkModel): + target = models.ForeignKey(ForeignKeyTarget, help_text='Target', + verbose_name='Target', + limit_choices_to={"name__startswith": "limited-"}, + on_delete=models.CASCADE) + + # Nullable ForeignKey class NullableForeignKeySource(RESTFrameworkModel): name = models.CharField(max_length=100) diff --git a/tests/test_relations_pk.py b/tests/test_relations_pk.py index 3317d6251e..31b6bb8677 100644 --- a/tests/test_relations_pk.py +++ b/tests/test_relations_pk.py @@ -5,10 +5,10 @@ from rest_framework import serializers from tests.models import ( - ForeignKeySource, ForeignKeyTarget, ManyToManySource, ManyToManyTarget, - NullableForeignKeySource, NullableOneToOneSource, - NullableUUIDForeignKeySource, OneToOnePKSource, OneToOneTarget, - UUIDForeignKeyTarget + ForeignKeySource, ForeignKeySourceWithLimitedChoices, ForeignKeyTarget, + ManyToManySource, ManyToManyTarget, NullableForeignKeySource, + NullableOneToOneSource, NullableUUIDForeignKeySource, OneToOnePKSource, + OneToOneTarget, UUIDForeignKeyTarget ) @@ -38,6 +38,12 @@ class Meta: fields = ('id', 'name', 'target') +class ForeignKeySourceWithLimitedChoicesSerializer(serializers.ModelSerializer): + class Meta: + model = ForeignKeySourceWithLimitedChoices + fields = ("id", "target") + + # Nullable ForeignKey class NullableForeignKeySourceSerializer(serializers.ModelSerializer): class Meta: @@ -360,6 +366,18 @@ class Meta(ForeignKeySourceSerializer.Meta): serializer.is_valid(raise_exception=True) assert 'target' not in serializer.validated_data + def test_queryset_size_without_limited_choices(self): + limited_target = ForeignKeyTarget(name="limited-target") + limited_target.save() + queryset = ForeignKeySourceSerializer().fields["target"].get_queryset() + assert len(queryset) == 3 + + def test_queryset_size_with_limited_choices(self): + limited_target = ForeignKeyTarget(name="limited-target") + limited_target.save() + queryset = ForeignKeySourceWithLimitedChoicesSerializer().fields["target"].get_queryset() + assert len(queryset) == 1 + class PKNullableForeignKeyTests(TestCase): def setUp(self):