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

Introduced WritableNestedSerializer

This commit is contained in:
Jeremy Stretch
2018-04-04 15:39:14 -04:00
parent 72c518bcb7
commit db3cbaf83b

View File

@ -5,6 +5,7 @@ import pytz
from django.conf import settings from django.conf import settings
from django.contrib.contenttypes.models import ContentType from django.contrib.contenttypes.models import ContentType
from django.core.exceptions import ObjectDoesNotExist
from django.db.models import ManyToManyField from django.db.models import ManyToManyField
from django.http import Http404 from django.http import Http404
from rest_framework import mixins from rest_framework import mixins
@ -36,6 +37,64 @@ class IsAuthenticatedOrLoginNotRequired(BasePermission):
return request.user.is_authenticated return request.user.is_authenticated
#
# Fields
#
class ChoiceFieldSerializer(Field):
"""
Represent a ChoiceField as {'value': <DB value>, 'label': <string>}.
"""
def __init__(self, choices, **kwargs):
self._choices = dict()
for k, v in choices:
# Unpack grouped choices
if type(v) in [list, tuple]:
for k2, v2 in v:
self._choices[k2] = v2
else:
self._choices[k] = v
super(ChoiceFieldSerializer, self).__init__(**kwargs)
def to_representation(self, obj):
return {'value': obj, 'label': self._choices[obj]}
def to_internal_value(self, data):
return data
class ContentTypeFieldSerializer(Field):
"""
Represent a ContentType as '<app_label>.<model>'
"""
def to_representation(self, obj):
return "{}.{}".format(obj.app_label, obj.model)
def to_internal_value(self, data):
app_label, model = data.split('.')
try:
return ContentType.objects.get_by_natural_key(app_label=app_label, model=model)
except ContentType.DoesNotExist:
raise ValidationError("Invalid content type")
class TimeZoneField(Field):
"""
Represent a pytz time zone.
"""
def to_representation(self, obj):
return obj.zone if obj else None
def to_internal_value(self, data):
if not data:
return ""
try:
return pytz.timezone(str(data))
except pytz.exceptions.UnknownTimeZoneError:
raise ValidationError('Invalid time zone "{}"'.format(data))
# #
# Serializers # Serializers
# #
@ -67,58 +126,15 @@ class ValidatedModelSerializer(ModelSerializer):
return data return data
class ChoiceFieldSerializer(Field): class WritableNestedSerializer(ModelSerializer):
""" """
Represent a ChoiceField as {'value': <DB value>, 'label': <string>}. Returns a nested representation of an object on read, but accepts only a primary key on write.
""" """
def __init__(self, choices, **kwargs):
self._choices = dict()
for k, v in choices:
# Unpack grouped choices
if type(v) in [list, tuple]:
for k2, v2 in v:
self._choices[k2] = v2
else:
self._choices[k] = v
super(ChoiceFieldSerializer, self).__init__(**kwargs)
def to_representation(self, obj):
return {'value': obj, 'label': self._choices[obj]}
def to_internal_value(self, data): def to_internal_value(self, data):
return self._choices.get(data)
class ContentTypeFieldSerializer(Field):
"""
Represent a ContentType as '<app_label>.<model>'
"""
def to_representation(self, obj):
return "{}.{}".format(obj.app_label, obj.model)
def to_internal_value(self, data):
app_label, model = data.split('.')
try: try:
return ContentType.objects.get_by_natural_key(app_label=app_label, model=model) return self.Meta.model.objects.get(pk=data)
except ContentType.DoesNotExist: except ObjectDoesNotExist:
raise ValidationError("Invalid content type") raise ValidationError("Invalid ID")
class TimeZoneField(Field):
"""
Represent a pytz time zone.
"""
def to_representation(self, obj):
return obj.zone if obj else None
def to_internal_value(self, data):
if not data:
return ""
try:
return pytz.timezone(str(data))
except pytz.exceptions.UnknownTimeZoneError:
raise ValidationError('Invalid time zone "{}"'.format(data))
# #