Add support for models with custom primary key

- serializer can treat primary key field as read-only during
  update, but accept it as writable during create when it is
  not auto-generated
This commit is contained in:
Brad MacPhee 2016-09-21 11:37:53 -03:00 committed by Brad MacPhee
parent 93e75ec138
commit 00148d545c
2 changed files with 36 additions and 2 deletions

View File

@ -994,7 +994,7 @@ class ModelSerializer(Serializer):
# Determine any extra field arguments and hidden fields that
# should be included
extra_kwargs = self.get_extra_kwargs()
extra_kwargs = self.get_extra_kwargs(info)
extra_kwargs, hidden_fields = self.get_uniqueness_extra_kwargs(
field_names, declared_fields, extra_kwargs
)
@ -1289,7 +1289,7 @@ class ModelSerializer(Serializer):
# Methods for determining additional keyword arguments to apply...
def get_extra_kwargs(self):
def get_extra_kwargs(self, model_info):
"""
Return a dictionary mapping field names to a dictionary of
additional keyword arguments.
@ -1317,6 +1317,8 @@ class ModelSerializer(Serializer):
(self.__class__.__module__, self.__class__.__name__)
)
if not model_info.pk.auto_created and self.instance:
extra_kwargs.setdefault(model_info.pk.name, {})['read_only'] = True
return extra_kwargs
def get_uniqueness_extra_kwargs(self, field_names, declared_fields, extra_kwargs):

View File

@ -42,6 +42,10 @@ class OneFieldModel(models.Model):
char_field = models.CharField(max_length=100)
class CustomPrimaryKeyModel(models.Model):
char_field = models.CharField(primary_key=True, max_length=100)
class RegularFieldsModel(models.Model):
"""
A model class for testing regular flat fields.
@ -153,6 +157,34 @@ class TestModelSerializer(TestCase):
assert str(excinfo.exception).startswith(msginitial)
class TestCustomPrimaryKeyModelSerializer(TestCase):
class TestSerializer(serializers.ModelSerializer):
class Meta:
model = CustomPrimaryKeyModel
fields = ('char_field',)
def test_create_method(self):
serializer = self.TestSerializer(data={
'char_field': 'foo'
})
assert serializer.is_valid()
instance = serializer.save()
assert 'foo' == instance.pk
def test_pk_read_only_on_update(self):
instance = CustomPrimaryKeyModel.objects.create(
char_field='foo'
)
instance.save()
serializer = self.TestSerializer(instance=instance, data={
'char_field': 'bar'
})
assert serializer.is_valid()
updated_instance = serializer.save()
assert 'bar' != updated_instance.pk
class TestRegularFieldMappings(TestCase):
def test_regular_fields(self):
"""