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:
@ -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):
|
||||||
|
@ -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
|
||||||
|
Reference in New Issue
Block a user