|
@@ -21,6 +21,10 @@ class ServiceUnavailable(APIException):
|
|
|
default_detail = "Service temporarily unavailable, please try again later."
|
|
default_detail = "Service temporarily unavailable, please try again later."
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
+class SerializerNotFound(Exception):
|
|
|
|
|
+ pass
|
|
|
|
|
+
|
|
|
|
|
+
|
|
|
def get_serializer_for_model(model, prefix=''):
|
|
def get_serializer_for_model(model, prefix=''):
|
|
|
"""
|
|
"""
|
|
|
Dynamically resolve and return the appropriate serializer for a model.
|
|
Dynamically resolve and return the appropriate serializer for a model.
|
|
@@ -32,7 +36,9 @@ def get_serializer_for_model(model, prefix=''):
|
|
|
try:
|
|
try:
|
|
|
return dynamic_import(serializer_name)
|
|
return dynamic_import(serializer_name)
|
|
|
except AttributeError:
|
|
except AttributeError:
|
|
|
- return None
|
|
|
|
|
|
|
+ raise SerializerNotFound(
|
|
|
|
|
+ "Could not determine serializer for {}.{} with prefix '{}'".format(app_name, model_name, prefix)
|
|
|
|
|
+ )
|
|
|
|
|
|
|
|
|
|
|
|
|
#
|
|
#
|
|
@@ -100,6 +106,10 @@ class ChoiceField(Field):
|
|
|
|
|
|
|
|
return data
|
|
return data
|
|
|
|
|
|
|
|
|
|
+ @property
|
|
|
|
|
+ def choices(self):
|
|
|
|
|
+ return self._choices
|
|
|
|
|
+
|
|
|
|
|
|
|
|
class ContentTypeField(RelatedField):
|
|
class ContentTypeField(RelatedField):
|
|
|
"""
|
|
"""
|
|
@@ -110,10 +120,6 @@ class ContentTypeField(RelatedField):
|
|
|
"invalid": "Invalid value. Specify a content type as '<app_label>.<model_name>'.",
|
|
"invalid": "Invalid value. Specify a content type as '<app_label>.<model_name>'.",
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
- # Can't set this as an attribute because it raises an exception when the field is read-only
|
|
|
|
|
- def get_queryset(self):
|
|
|
|
|
- return ContentType.objects.all()
|
|
|
|
|
-
|
|
|
|
|
def to_internal_value(self, data):
|
|
def to_internal_value(self, data):
|
|
|
try:
|
|
try:
|
|
|
app_label, model = data.split('.')
|
|
app_label, model = data.split('.')
|
|
@@ -234,9 +240,10 @@ class ModelViewSet(_ModelViewSet):
|
|
|
# exists
|
|
# exists
|
|
|
request = self.get_serializer_context()['request']
|
|
request = self.get_serializer_context()['request']
|
|
|
if request.query_params.get('brief', False):
|
|
if request.query_params.get('brief', False):
|
|
|
- serializer_class = get_serializer_for_model(self.queryset.model, prefix='Nested')
|
|
|
|
|
- if serializer_class is not None:
|
|
|
|
|
- return serializer_class
|
|
|
|
|
|
|
+ try:
|
|
|
|
|
+ return get_serializer_for_model(self.queryset.model, prefix='Nested')
|
|
|
|
|
+ except SerializerNotFound:
|
|
|
|
|
+ pass
|
|
|
|
|
|
|
|
# Fall back to the hard-coded serializer class
|
|
# Fall back to the hard-coded serializer class
|
|
|
return self.serializer_class
|
|
return self.serializer_class
|
|
@@ -256,10 +263,14 @@ class FieldChoicesViewSet(ViewSet):
|
|
|
self._fields = OrderedDict()
|
|
self._fields = OrderedDict()
|
|
|
for cls, field_list in self.fields:
|
|
for cls, field_list in self.fields:
|
|
|
for field_name in field_list:
|
|
for field_name in field_list:
|
|
|
|
|
+
|
|
|
model_name = cls._meta.verbose_name.lower().replace(' ', '-')
|
|
model_name = cls._meta.verbose_name.lower().replace(' ', '-')
|
|
|
key = ':'.join([model_name, field_name])
|
|
key = ':'.join([model_name, field_name])
|
|
|
|
|
+
|
|
|
|
|
+ serializer = get_serializer_for_model(cls)()
|
|
|
choices = []
|
|
choices = []
|
|
|
- for k, v in cls._meta.get_field(field_name).choices:
|
|
|
|
|
|
|
+
|
|
|
|
|
+ for k, v in serializer.get_fields()[field_name].choices.items():
|
|
|
if type(v) in [list, tuple]:
|
|
if type(v) in [list, tuple]:
|
|
|
for k2, v2 in v:
|
|
for k2, v2 in v:
|
|
|
choices.append({
|
|
choices.append({
|