使用嵌套可写序列化程序的django rest框架文件上载

eph*_*hes 7 python django django-rest-framework

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‘,)
Run Code Online (Sandbox Code Playgroud)

注释具有图像外键属性,因此图像可能具有多个注释.我想通过对图像端点的发布请求创建带有嵌套注释的图像,包括该图像的注释列表.将我的数据json编码发送到images端点确实有效并创建带有适当注释的图像.

但是当我尝试上传实际图像时,我必须使用多部分/表单编码的post请求而不是json,以使fileupload成为可能.现在我很难获得此请求中包含的嵌套图像注释列表.也许我可以在一些表单字段中放置一个json编码的字符串,并在视图中手动解析它,覆盖request.DATA,但这似乎真的很难看.

我想知道是否有更好的方法来实现我想要做的事情:).

Ale*_* jg 7

我发现解决这个问题的最好方法是编写一个自定义解析器来解析传入的多部分请求.我一直在使用formencode来进行实际的解析,但你可以使用任何嵌套的formdata库.这需要很少的代码:

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)
Run Code Online (Sandbox Code Playgroud)

然后在你的 ViewSet

class ImageViewSet(viewsets.ModelViewSet):
    ...
    parsers = (MultipartFormencodeParser,)
    ...
Run Code Online (Sandbox Code Playgroud)

Formencode将列表表示为<key>-<index>编码表单数据中的条目和嵌套属性<item>.<proprety>.因此,在您的示例中,客户端需要将注释编码为"annotation-1.name"请求中的类似内容.显然,你仍然需要手动处理嵌套数据的更新的串行器作为REST框架文件中提到这里


Sco*_*d77 1

很难获取请求中包含的图像注释的嵌套列表是什么意思?当您发送multpart/form-datapost请求时,嵌套的表示法列表数据是否包含在request.data中?(请使用和request.data代替)。请使用一些调试工具,例如检查您的.request.DATArequest.FILESpdbrequest.data

为了支持可写嵌套序列化器,我认为你应该重写方法create()的函数POST,你可以从这里找到更多细节。抱歉没有直接给出答案,我需要有关您的型号的更多详细信息。

如果你想发布JSON而不是multipart/form-data,你可以使用base64代表数字(但文件的大小将增长近 33%)。