I've started using Django REST Framework, and it is simply magic!
Here is a technique I've used to input lists of primitive types and serializers with many=True
from functools import partial from rest_framework import viewsets from rest_framework.response import Response from rest_framework import status from my_app.serializers import MyNestedModelSerializer ... class MyNestedModelViewSet(viewsets.ViewSet): serializer_class = MyNestedModelSerializer def create(self, request): serializer = self.serializer_class(data=request.data) # get the submodel list serializer since it can't render/parse html submodel_list_serializer = serializer.fields['submodels'] # make a partial function by setting the submodel list serializer partial_get_value = partial(custom_get_value, submodel_list_serializer) # monkey patch submodel_list_serializer.get_value() with partial function submodel_list_serializer.get_value = partial_get_value if serializer.is_valid(): simulate_data = serializer.save() # do stuff ... return Response(serializer.data, status=status.HTTP_201_CREATED) return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
The function `custom_get_value()` uses JSON to parse the input:
def custom_get_value(serializer, dictionary): if serializer.field_name not in dictionary: if getattr(serializer.root, 'partial', False): return empty # We override the default field access in order to support # lists in HTML forms. if html.is_html_input(dictionary): listval = dictionary.getlist(serializer.field_name) if len(listval) == 1 and isinstance(listval[0], basestring): # get only item in value list, strip leading/trailing whitespace listval = listval[0].strip() # add brackets if missing so that it's a JSON list if not (listval.startswith('[') and listval.endswith(']')): listval = '[' + listval + ']' # try to deserialize JSON string try: listval = json.loads(listval) except ValueError as err: # return original string and log error pass # set the field with the new value list dictionary.setlist(serializer.field_name, listval) val = dictionary.getlist(serializer.field_name, []) if len(val) > 0: # Support QueryDict lists in HTML input. return val return html.parse_html_list(dictionary, prefix=serializer.field_name) return dictionary.get(serializer.field_name, empty)
No comments:
Post a Comment