From 1129a8dacd55db73c627da707f216faa2aa82cb5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Benjamin=20Sch=C3=A4fer?= Date: Thu, 17 Feb 2022 16:51:01 +0100 Subject: [PATCH] Detect underlying field for OneToOne primary key --- rest_framework/serializers.py | 4 ++++ tests/test_serializer.py | 18 ++++++++++++++++++ 2 files changed, 22 insertions(+) diff --git a/rest_framework/serializers.py b/rest_framework/serializers.py index 389680517..d3af3d15a 100644 --- a/rest_framework/serializers.py +++ b/rest_framework/serializers.py @@ -1234,6 +1234,10 @@ class ModelSerializer(Serializer): if model_field.one_to_one and model_field.primary_key: field_class = self.serializer_related_field field_kwargs['queryset'] = model_field.related_model.objects + pk_field = field_mapping[model_field.foreign_related_fields[0]] + pk_field_kwargs = get_field_kwargs(field_name, model_field.foreign_related_fields[0]) + pk_field_kwargs.pop("model_field") + field_kwargs["pk_field"] = pk_field(**pk_field_kwargs) if 'choices' in field_kwargs: # Fields with choices get coerced into `ChoiceField` diff --git a/tests/test_serializer.py b/tests/test_serializer.py index c4c29ba4a..bad9de9b8 100644 --- a/tests/test_serializer.py +++ b/tests/test_serializer.py @@ -762,3 +762,21 @@ class Test8301Regression: assert (s.data | {}).__class__ == s.data.__class__ assert ({} | s.data).__class__ == s.data.__class__ + + +class TestRelatedFieldTypes: + + def test_one_to_one_field(self): + class MyModelA(models.Model): + id = models.DecimalField(max_digits=4, decimal_places=2, primary_key=True) + + class MyModelB(models.Model): + id = models.OneToOneField(MyModelA, models.CASCADE, primary_key=True) + + class MyModelBSerializer(serializers.ModelSerializer): + class Meta: + model = MyModelB + fields = "__all__" + + ser = MyModelBSerializer() + assert type(ser.fields["id"].pk_field) == fields.DecimalField