diff --git a/docs/release-notes/version-2.10.md b/docs/release-notes/version-2.10.md index cae40de5a..966b5e1e2 100644 --- a/docs/release-notes/version-2.10.md +++ b/docs/release-notes/version-2.10.md @@ -8,6 +8,7 @@ ### Bug Fixes +* [#5176](https://github.com/netbox-community/netbox/issues/5176) - Enforce content type restrictions when creating objects via the REST API * [#5358](https://github.com/netbox-community/netbox/issues/5358) - Fix user table configuration for VM interfaces * [#5374](https://github.com/netbox-community/netbox/issues/5374) - Fix exception thrown when tracing mid-point * [#5376](https://github.com/netbox-community/netbox/issues/5376) - Correct invalid custom field filter logic values diff --git a/netbox/netbox/api/fields.py b/netbox/netbox/api/fields.py index e861edc71..fb3eef76f 100644 --- a/netbox/netbox/api/fields.py +++ b/netbox/netbox/api/fields.py @@ -94,14 +94,14 @@ class ContentTypeField(RelatedField): def to_internal_value(self, data): try: app_label, model = data.split('.') - return ContentType.objects.get_by_natural_key(app_label=app_label, model=model) + return self.queryset.get(app_label=app_label, model=model) except ObjectDoesNotExist: self.fail('does_not_exist', content_type=data) - except (TypeError, ValueError): + except (AttributeError, TypeError, ValueError): self.fail('invalid') def to_representation(self, obj): - return "{}.{}".format(obj.app_label, obj.model) + return f"{obj.app_label}.{obj.model}" class TimeZoneField(serializers.Field): diff --git a/netbox/netbox/api/serializers.py b/netbox/netbox/api/serializers.py index c5ecf9372..3a8641efc 100644 --- a/netbox/netbox/api/serializers.py +++ b/netbox/netbox/api/serializers.py @@ -6,11 +6,10 @@ from rest_framework.exceptions import ValidationError from utilities.utils import dict_to_filter_params -# 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(serializers.ModelSerializer): """ - Extends the built-in ModelSerializer to enforce calling clean() on the associated model during validation. + Extends the built-in ModelSerializer to enforce calling full_clean() on a copy of the associated instance during + validation. (DRF does not do this by default; see https://github.com/encode/django-rest-framework/issues/3144) """ def validate(self, data): @@ -31,8 +30,7 @@ class ValidatedModelSerializer(serializers.ModelSerializer): instance = self.instance for k, v in attrs.items(): setattr(instance, k, v) - instance.clean() - instance.validate_unique() + instance.full_clean() return data