Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
- Raise exception if field is defined on the class and present in extra_kwargs or read_only_fields
- Do not overwrite options specified in extra_kwargs in get_uniqueness_extra_kwargs
  • Loading branch information
George-Cristian Bîrzan committed Jun 15, 2016
1 parent 798a971 commit badf777
Show file tree
Hide file tree
Showing 2 changed files with 51 additions and 6 deletions.
12 changes: 8 additions & 4 deletions rest_framework/serializers.py
Original file line number Diff line number Diff line change
Expand Up @@ -947,6 +947,11 @@ def get_fields(self):
# Determine any extra field arguments and hidden fields that
# should be included
extra_kwargs = self.get_extra_kwargs()
for field in extra_kwargs:
assert field not in declared_fields, (
"Field {} is declared on the class and also present in "
"extra_kwargs or read_only_fields".format(field)
)
extra_kwargs, hidden_fields = self.get_uniqueness_extra_kwargs(
field_names, declared_fields, extra_kwargs
)
Expand Down Expand Up @@ -1321,12 +1326,11 @@ def get_uniqueness_extra_kwargs(self, field_names, declared_fields, extra_kwargs
# add in a hidden field that populates it.
hidden_fields[unique_constraint_name] = HiddenField(default=default)

# Update `extra_kwargs` with any new options.
# Update `extra_kwargs` with any new options but don't overwrite old values.
for key, value in uniqueness_extra_kwargs.items():
if key in extra_kwargs:
extra_kwargs[key].update(value)
else:
extra_kwargs[key] = value
value.update(extra_kwargs[key])
extra_kwargs[key] = value

return extra_kwargs, hidden_fields

Expand Down
45 changes: 43 additions & 2 deletions tests/test_model_serializer.py
Original file line number Diff line number Diff line change
Expand Up @@ -933,8 +933,8 @@ class TestSerializer(serializers.ModelSerializer):

class Meta:
model = OneFieldModel
read_only_fields = ('char_field', 'non_model_field')
fields = read_only_fields
read_only_fields = ('char_field',)
fields = read_only_fields + ('non_model_field', )
extra_kwargs = {}

class ChildSerializer(TestSerializer):
Expand All @@ -955,3 +955,44 @@ class Meta(TestSerializer.Meta):
self.assertEqual(unicode_repr(ChildSerializer()), child_expected)
self.assertEqual(unicode_repr(TestSerializer()), test_expected)
self.assertEqual(unicode_repr(ChildSerializer()), child_expected)


class TestDeclaredFieldsConflict(TestCase):
def test_extra_kwargs_conflict(self):
class TestSerializer(serializers.ModelSerializer):
some_field = serializers.CharField()

class Meta:
model = OneFieldModel
extra_kwargs = {'some_field': {'read_only': True}}
with self.assertRaises(AssertionError):
TestSerializer().get_fields()

def test_read_only_fields_conflict(self):
class TestSerializer(serializers.ModelSerializer):
some_field = serializers.CharField()

class Meta:
model = OneFieldModel
read_only_fields = ('some_field', )
with self.assertRaises(AssertionError):
TestSerializer().get_fields()


class TestUniquenessOverride(TestCase):
def test_required_not_overwritten(self):
class TestModel(models.Model):
field_1 = models.IntegerField(null=True)
field_2 = models.IntegerField()

class Meta:
unique_together = (('field_1', 'field_2'),)

class TestSerializer(serializers.ModelSerializer):
class Meta:
model = TestModel
extra_kwargs = {'field_1': {'required': False}}

fields = TestSerializer().fields
self.assertFalse(fields['field_1'].required)
self.assertTrue(fields['field_2'].required)

0 comments on commit badf777

Please sign in to comment.