简体   繁体   English

DRF 上传多个文件

[英]DRF Upload multiple file

I'm using DRF to create an user with multiple attachments.我正在使用 DRF 创建具有多个附件的用户。 When you create an user you have to upload one or more files.创建用户时,您必须上传一个或多个文件。 When I make an update of an user which you load a new file (no other modified field) the response back the old instance.当我更新加载新文件(没有其他修改字段)的用户时,响应返回旧实例。

I solved by forcing the '_prefetched_objects_cache' attribute in the serializer before returning the instance.我通过在返回实例之前强制序列化程序中的 '_prefetched_objects_cache' 属性来解决。

setattr(instance, '_prefetched_objects_cache', True)

Is it correct?这是正确的吗? You have other solutions about it?你有其他解决方案吗? thanks谢谢

There is my code有我的代码

in models.py在models.py中

class User(models.Model):
   #field of user model

class Attachment(models.Model):
    class Meta:
        db_table = 'attachment'

    path = models.FileField()
    user = models.ForeignKey(User, on_delete=models.CASCADE, related_name='attachments')
    dt_created = models.DateTimeField(auto_now_add=True, verbose_name='Created')

in serializer.py在 serializer.py 中

class AttachmentSerializer(serializers.ModelSerializer):
    class Meta:
        model = Attachment
        fields = '__all__'

class UserSerializer(serializers.ModelSerializer):
  attachments = AttachmentSerializer(many=True, read_only=True)


  def create(self, validated_data):

      user = User.objects.create(**validated_data)

      for file_item in self.initial_data.getlist('attachments'):
         c = Attachment(path=file_item, user=user)
         c.save()
      return user

  def update(self, instance, validated_data):
      for item in validated_data:
          if User._meta.get_field(item):
              setattr(instance, item, validated_data[item])

       c = Attachment(path=self.context['request'].FILES['attachments'], user=instance)
       c.save()

       instance.save()
       setattr(instance, '_prefetched_objects_cache', True)
       return instance

in test.py在 test.py 中

io = StringIO.StringIO()
io.write('foo')
file = InMemoryUploadedFile(io, None, 'foo.txt', 'text', io.len, None)
file.seek(0)
self.user['attachments'] = [file, file]
data = self.user
response = self.client.post(url, data, format='multipart')
file = InMemoryUploadedFile(io, None, 'foo2.txt', 'text', io.len, None)
file.seek(0)
#url = url of user detail for update
local_user['attachments'].extend(response.data['attachments'])
local_user['attachments'].append(file)
data = local_user
response = self.client.put(path=url, data=data, format='multipart')

In case you use form for posting to DRF, you could use FormParser along with MultiPartParser if you're posting your data using forms如果您使用表单发布到 DRF,如果您使用表单发布数据,则可以将FormParserMultiPartParser一起使用

ex.前任。

...
from rest_framework.parsers import MultiPartParser, FormParser
...

class UserView(APIView):
    parser_classes = (FormParser, MultiPartParser)

    def post(self, request):
        ...

Files will be available under request.data or request.FILES as InMemoryUploadedFile instance.文件将在request.datarequest.FILES作为InMemoryUploadedFile实例可用。 You can proceed working with those in serializer or whatever fits better for you view logic.您可以继续使用序列化程序或任何更适合您查看逻辑的内容。

Don't forget to set enctype to multipart/form-data in your form, otherwise files won't get parsed properly ex.不要忘记在multipart/form-data中将enctype设置为multipart/form-data ,否则文件将无法正确解析。

<form action="..." method="POST" enctype="multipart/form-data">
  <input type="file" name="file-1" />
  <input type="file" name="file-2" />
</form>

I came across more of less the same problem some time back.前段时间我遇到了更多或更少相同的问题。 And this answer explains how i solve it.这个答案解释了我如何解决它。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM