Django Rest框架:使用FileField/ImageField的嵌套序列化程序

ste*_*ory 6 django-rest-framework

我有一个序列化程序遵循类似于以下的模型:

class Ticket:
    customer = Customer()
    ...
class Customer:
    signature = FileField()
    name = CharField()
Run Code Online (Sandbox Code Playgroud)

我想使用DRF的序列化程序来发布一个新的"Ticket",所以我发送带有签名文件和必要的'application/json'数据的multipart/form数据.

收集FILES和DATA后,生成的请求如下所示:

>>> request.FILES
<MultiValueDict: {u'customer.signature': [<InMemoryUploadedFile: signature.jpg (image/jpeg)>]}>
>>> data
{u'customer': {u'name': u'Test'}, ... }
>>> serializer = TicketSerializer(data=data, files=request.FILES)
>>> serializer.is_valid()
False
>>> serializer.errors
{'customer': [{'signature': [u'This field is required.']}]}
Run Code Online (Sandbox Code Playgroud)

如何使用DRF序列化器/字段填充"客户"层内的ImageFields/FileFields?

ste*_*ory 3

因为看来我不是唯一一个遇到这个问题的人,这是我想出的解决方案:

最直接的答案是获取上传的 ImageField/FileField 并将它们应用到序列化器的嵌套“数据”部分的适当位置。就我而言,这将位于“客户”字典中。

一旦文件被正确应用到数据中,我们就可以删除“files=”变量,因为所有文件现在都包含在数据中。

代码中的工作示例如下所示:

>>> request.FILES
<MultiValueDict: {u'customer.signature': [<InMemoryUploadedFile: signature.jpg (image/jpeg)>]}>
>>> data
{u'customer': {u'name': u'Test'}, ... }
if 'customer.signature' in request.FILES:
    data['customer']['signature_file'] = request.FILES['customer.signature']
>>> serializer = TicketSerializer(data=data)
>>> serializer.is_valid()
True
Run Code Online (Sandbox Code Playgroud)