[英]DRF Upload multiple file
我正在使用 DRF 創建具有多個附件的用戶。 創建用戶時,您必須上傳一個或多個文件。 當我更新加載新文件(沒有其他修改字段)的用戶時,響應返回舊實例。
我通過在返回實例之前強制序列化程序中的 '_prefetched_objects_cache' 屬性來解決。
setattr(instance, '_prefetched_objects_cache', True)
這是正確的嗎? 你有其他解決方案嗎? 謝謝
有我的代碼
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')
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
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')
如果您使用表單發布到 DRF,如果您使用表單發布數據,則可以將FormParser
與MultiPartParser
一起使用
前任。
...
from rest_framework.parsers import MultiPartParser, FormParser
...
class UserView(APIView):
parser_classes = (FormParser, MultiPartParser)
def post(self, request):
...
文件將在request.data
或request.FILES
作為InMemoryUploadedFile
實例可用。 您可以繼續使用序列化程序或任何更適合您查看邏輯的內容。
不要忘記在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>
前段時間我遇到了更多或更少相同的問題。 這個答案解釋了我如何解決它。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.