1
0
mirror of https://github.com/netbox-community/netbox.git synced 2024-05-10 07:54:54 +00:00

Fixes #2301: Fix model validation on assignment of ManyToMany fields via API patch

This commit is contained in:
Jeremy Stretch
2018-08-03 10:45:53 -04:00
parent b4f29978b3
commit 1bdfcd1dbe
2 changed files with 12 additions and 5 deletions

View File

@ -438,9 +438,13 @@ class ConfigContextTest(HttpStatusMixin, APITestCase):
def test_update_configcontext(self): def test_update_configcontext(self):
region1 = Region.objects.create(name='Test Region 1', slug='test-region-1')
region2 = Region.objects.create(name='Test Region 2', slug='test-region-2')
data = { data = {
'name': 'Test Config Context X', 'name': 'Test Config Context X',
'weight': 999, 'weight': 999,
'regions': [region1.pk, region2.pk],
'data': {'foo': 'XXX'} 'data': {'foo': 'XXX'}
} }
@ -452,6 +456,7 @@ class ConfigContextTest(HttpStatusMixin, APITestCase):
configcontext1 = ConfigContext.objects.get(pk=response.data['id']) configcontext1 = ConfigContext.objects.get(pk=response.data['id'])
self.assertEqual(configcontext1.name, data['name']) self.assertEqual(configcontext1.name, data['name'])
self.assertEqual(configcontext1.weight, data['weight']) self.assertEqual(configcontext1.weight, data['weight'])
self.assertEqual(sorted([r.pk for r in configcontext1.regions.all()]), sorted(data['regions']))
self.assertEqual(configcontext1.data, data['data']) self.assertEqual(configcontext1.data, data['data'])
def test_delete_configcontext(self): def test_delete_configcontext(self):

View File

@ -126,6 +126,8 @@ class SerializedPKRelatedField(PrimaryKeyRelatedField):
# Serializers # Serializers
# #
# TODO: We should probably take a fresh look at exactly what we're doing with this. There might be a more elegant
# way to enforce model validation on the serializer.
class ValidatedModelSerializer(ModelSerializer): class ValidatedModelSerializer(ModelSerializer):
""" """
Extends the built-in ModelSerializer to enforce calling clean() on the associated model during validation. Extends the built-in ModelSerializer to enforce calling clean() on the associated model during validation.
@ -137,13 +139,13 @@ class ValidatedModelSerializer(ModelSerializer):
attrs.pop('custom_fields', None) attrs.pop('custom_fields', None)
attrs.pop('tags', None) attrs.pop('tags', None)
# Skip ManyToManyFields
for field in self.Meta.model._meta.get_fields():
if isinstance(field, ManyToManyField):
attrs.pop(field.name, None)
# Run clean() on an instance of the model # Run clean() on an instance of the model
if self.instance is None: if self.instance is None:
model = self.Meta.model
# Ignore ManyToManyFields for new instances (a PK is needed for validation)
for field in model._meta.get_fields():
if isinstance(field, ManyToManyField) and field.name in attrs:
attrs.pop(field.name)
instance = self.Meta.model(**attrs) instance = self.Meta.model(**attrs)
else: else:
instance = self.instance instance = self.instance