Loading a django rest frame file with nested rewritable serializers

class AnnotationSerializer(serializers.HyperlinkedModelSerializer): class Meta: model = Annotation class ImageSerializer(serializers.HyperlinkedModelSerializer): annotations = AnnotationSerializer(many=True, required=False) class Meta: depth = 1 model = Image exclude = ('owner',) 

Annotations have an image foreign key attribute, so images have potentially multiple annotations. I'd like to create an image with nested annotations through a request to send the endpoint of the image, including a list of annotations for this image. Posting json data encoded to the endpoint of the images works and creates the image with the corresponding annotations.

But when I try to upload the actual image, I have to use an email request with multipart / form support instead of json to make file upload possible. And now it’s hard for me to get the list of image annotations you enclosed in this query. Maybe I can put the json encoded string in some form field and manually parse it in the view by rewriting request.DATA, but that seems really ugly.

I wonder if the best way to do what I'm trying to do is :).

+6
source share
3 answers

The easiest way to solve this problem is to write your own parser that parses an incoming multi-page request. I used formencode to do the actual parsing, but you can use any formdata nested library. This requires surprisingly little code:

 from rest_framework import parsers from formencode.variabledecode import variable_decode class MultipartFormencodeParser(parsers.MultiPartParser): def parse(self, stream, media_type=None, parser_context=None): result = super().parse( stream, media_type=media_type, parser_context=parser_context ) data = variable_decode(result.data) return parsers.DataAndFiles(data, result.files) 

And then in the ViewSet

 class ImageViewSet(viewsets.ModelViewSet): ... parsers = (MultipartFormencodeParser,) ... 

Formencode represents lists as <key>-<index> entries in encoded form data and nested properties as <item>.<proprety> . Thus, in your example, the client will need to code the annotations as something like "annotation-1.name" in the request. Obviously, you still have to handle updating the embedded data manually in the serializer, as indicated in the documentation for the rest of the structure here

+5
source

What do you mean, that with difficult time, get a nested list of image annotations in the request? When you submit a multpart/form-data request, is the data in the list of nested notations included in request.data? (Use request.data instead of request.data and request.FILES ). Please use some debugging tools like pdb to check request.data .

To support a writable nested serializer, I think you should override the create() function for the POST method, and you can find more details from here . Sorry for not giving the answer directly, I need more information about your models.

And if you want to send JSON instead of multipart/form-data , you can use base64 to represent the shape (but the file size will grow by almost 33% more).

+1
source

you can use formencode.variabledecode.variable_decode ()

Example:

 class ImageSerializer(serializers.HyperlinkedModelSerializer): ... def to_internal_value(self, value): return super(ImageSerializer, self).to_internal_value(variable_decode(value)) 
+1
source

Source: https://habr.com/ru/post/973775/


All Articles