【问题标题】:django rest framework file upload with nested writable serializers使用嵌套的可写序列化程序上传 django rest 框架文件
【发布时间】:2014-10-07 03:01:24
【问题描述】:
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‘,)

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

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

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

【问题讨论】:

  • 你找到解决办法了吗?
  • 不,我最终使用了一个特殊的图像端点。
  • 我也面临同样的问题。特殊端点是什么意思?

标签: python django django-rest-framework


【解决方案1】:

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

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)

然后在你的ViewSet

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

Formencode 将列表表示为编码表单数据中的<key>-<index> 条目,并将嵌套属性表示为<item>.<proprety>。因此,在您的示例中,客户端需要在请求中将注释编码为 "annotation-1.name" 之类的东西。显然,您仍然需要在序列化程序中手动处理嵌套数据的更新,如其余框架文档中所述here

【讨论】:

  • 如果您也有嵌套文件,那么您可以通过执行 files = variable_decode(result.files) 并将其传递给 return parsers.DataAndFiles(data, files) 来修改这个出色的答案
【解决方案2】:

你可以使用formencode.variabledecode.variable_decode()

示例:

class ImageSerializer(serializers.HyperlinkedModelSerializer):

    ...

    def to_internal_value(self, value):
        return super(ImageSerializer, self).to_internal_value(variable_decode(value))

【讨论】:

    【解决方案3】:

    你是什么意思很难得到嵌套的图像注释列表包含在请求中?当您发送multpart/form-data post 请求时,request.data 中是否包含嵌套符号列表数据? (请使用request.data 而不是request.DATArequest.FILES)。请使用pdb 等调试工具检查您的request.data

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

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

    【讨论】:

      猜你喜欢
      • 2015-08-14
      • 2019-10-13
      • 2019-12-23
      • 2021-06-23
      • 2016-05-14
      • 2016-09-03
      • 2018-12-13
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多