Просмотр исходного кода

Introduced WritableNestedSerializer

Jeremy Stretch 7 лет назад
Родитель
Сommit
db3cbaf83b
1 измененных файлов с 45 добавлено и 29 удалено
  1. 45 29
      netbox/utilities/api.py

+ 45 - 29
netbox/utilities/api.py

@@ -5,6 +5,7 @@ import pytz
 
 from django.conf import settings
 from django.contrib.contenttypes.models import ContentType
+from django.core.exceptions import ObjectDoesNotExist
 from django.db.models import ManyToManyField
 from django.http import Http404
 from rest_framework import mixins
@@ -37,36 +38,9 @@ class IsAuthenticatedOrLoginNotRequired(BasePermission):
 
 
 #
-# Serializers
+# Fields
 #
 
-class ValidatedModelSerializer(ModelSerializer):
-    """
-    Extends the built-in ModelSerializer to enforce calling clean() on the associated model during validation.
-    """
-    def validate(self, data):
-
-        # Remove custom field data (if any) prior to model validation
-        attrs = data.copy()
-        attrs.pop('custom_fields', None)
-
-        # Run clean() on an instance of the model
-        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)
-        else:
-            instance = self.instance
-            for k, v in attrs.items():
-                setattr(instance, k, v)
-        instance.clean()
-
-        return data
-
-
 class ChoiceFieldSerializer(Field):
     """
     Represent a ChoiceField as {'value': <DB value>, 'label': <string>}.
@@ -86,7 +60,7 @@ class ChoiceFieldSerializer(Field):
         return {'value': obj, 'label': self._choices[obj]}
 
     def to_internal_value(self, data):
-        return self._choices.get(data)
+        return data
 
 
 class ContentTypeFieldSerializer(Field):
@@ -121,6 +95,48 @@ class TimeZoneField(Field):
             raise ValidationError('Invalid time zone "{}"'.format(data))
 
 
+#
+# Serializers
+#
+
+class ValidatedModelSerializer(ModelSerializer):
+    """
+    Extends the built-in ModelSerializer to enforce calling clean() on the associated model during validation.
+    """
+    def validate(self, data):
+
+        # Remove custom field data (if any) prior to model validation
+        attrs = data.copy()
+        attrs.pop('custom_fields', None)
+
+        # Run clean() on an instance of the model
+        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)
+        else:
+            instance = self.instance
+            for k, v in attrs.items():
+                setattr(instance, k, v)
+        instance.clean()
+
+        return data
+
+
+class WritableNestedSerializer(ModelSerializer):
+    """
+    Returns a nested representation of an object on read, but accepts only a primary key on write.
+    """
+    def to_internal_value(self, data):
+        try:
+            return self.Meta.model.objects.get(pk=data)
+        except ObjectDoesNotExist:
+            raise ValidationError("Invalid ID")
+
+
 #
 # Viewsets
 #