Django REST上传多个带数据的文件。

我试图创建一个端点,接受(keyvalue)数据和多个文件。用户可以发送 serial 和多个文件连同他的请求。上传的文件必须保存在 FileModel 并添加一个关系到 RequestModel. 问题是当我发送请求时 RequestSerializer 解不开 files 而我得到一个关于缺少 files 领域。

#tests.py

def test_create_request_with_files(self):

    with tempfile.NamedTemporaryFile() as file:
        file.write(b"SomeFakeData")
        file.seek(0)
        request = {
            'files': [file],
            'serial': "SomeSerial",
        }
        res = self.client.post(
            '/CreateRequest/', request, format='multipart')
        print(res.data)
        self.assertEqual(res.status_code, status.HTTP_201_CREATED)
#---------------------------------------------------------------------------

# models.py

class FileModel(models.Model):
    file = models.FileField(upload_to='upload_files')


class RequestModel(models.Model):
    serial = models.CharField(max_length=100)
    files = models.ManyToManyField('FileModel', blank=True)

    def __str__(self):
        return str(self.id)
#---------------------------------------------------------------------------

# serializers.py

class FileSerializer(serializers.ModelSerializer):
    class Meta:
        model = FileModel
        fields = '__all__'
        read_only_fields = ('id',)


class RequestSerializer(serializers.ModelSerializer):
    files = FileSerializer(many=True)

    def create(self, validated_data):
        files = validated_data.pop('files')
        request_model = RequestModel.objects.create(**validated_data)
        for file in files:
            file_model = FileModel.objects.create(file=file)
            request_model.files.add(file_model)
        request_model.save()
        return request_model

    class Meta:
        model = RequestModel
        fields = '__all__'
        read_only_fields = ('id')
#---------------------------------------------------------------------------

#views.py

class RequestList(generics.ListCreateAPIView):
    queryset = RequestModel.objects.all()
    serializer_class = RequestSerializer
    parser_classes = (FormParser, MultiPartParser)

    def post(self, request, *args, **kwargs):
        serializer = RequestSerializer(data=request.data)
        if serializer.is_valid():
            request_model = serializer.save()
            return Response(serializer.data, status=status.HTTP_201_CREATED)
        return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)

测试的输出。

{'files': [ErrorDetail(string='This field is required.', code='required')]}
Fs
======================================================================
FAIL
----------------------------------------------------------------------
Traceback (most recent call last):
  File ".tests.py", line 95, in test_create_request_with_files 
    self.assertEqual(res.status_code, status.HTTP_201_CREATED)
AssertionError: 400 != 201

解决方案:

这不是django的问题。当你使用 multipart/form-data. 列表将被转换为 [object Object] 字符串.而是尝试。file1, file2 等等…

我将使用一个动态解析器,如

        count = 1
        files = []
        f = request.data.get('file{}'.fomat(count))
        while f is not None:
            files.append(f)
            count += 1
            f = request.data.get('file{}'.fomat(count))

给TA打赏
共{{data.count}}人
人已打赏
未分类

AIDE的数据库默认添加的路径是什么?

2022-9-9 23:28:42

未分类

如何操作jQuery Clone删除属性

2022-9-9 23:28:44

0 条回复 A文章作者 M管理员
    暂无讨论,说说你的看法吧
个人中心
购物车
优惠劵
今日签到
有新私信 私信列表
搜索