Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/python-3.x/18.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/django/20.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 3.x 如何在Django Rest框架中使用base64上传多个文件?_Python 3.x_Django_Vue.js_Django Rest Framework - Fatal编程技术网

Python 3.x 如何在Django Rest框架中使用base64上传多个文件?

Python 3.x 如何在Django Rest框架中使用base64上传多个文件?,python-3.x,django,vue.js,django-rest-framework,Python 3.x,Django,Vue.js,Django Rest Framework,我开始学习DRF,并尝试在VueJs上克隆Twitter来提高自己 在VueJs端,我使用FileReader进行文件上传,并在提交表单时将上传图像的base64代码发送到DRF。在DRF方面,我将这些base64代码转换为ContentFile,但最后我得到了下面提到的错误 {'files': [{'non_field_errors': [ErrorDetail(string='Invalid data. Expected a dictionary, but got ContentFile.'

我开始学习DRF,并尝试在VueJs上克隆Twitter来提高自己

在VueJs端,我使用FileReader进行文件上传,并在提交表单时将上传图像的base64代码发送到DRF。在DRF方面,我将这些base64代码转换为ContentFile,但最后我得到了下面提到的错误

{'files': [{'non_field_errors': [ErrorDetail(string='Invalid data. Expected a dictionary, but got ContentFile.', code='invalid')]}, {'non_field_errors': [ErrorDetail(string='Invalid data. Expected a dictionary, but got ContentFile.', code='invalid')]}]}
Internal Server Error: /api/add-tweet/
Traceback (most recent call last):
  File "C:\Users\adilc\Desktop\twitter-vue-django\twitter\lib\site-packages\django\core\handlers\exception.py", line 47, in inner
    response = get_response(request)
  File "C:\Users\adilc\Desktop\twitter-vue-django\twitter\lib\site-packages\django\core\handlers\base.py", line 204, in _get_response
    response = response.render()
  File "C:\Users\adilc\Desktop\twitter-vue-django\twitter\lib\site-packages\django\template\response.py", line 105, in render
    self.content = self.rendered_content
  File "C:\Users\adilc\Desktop\twitter-vue-django\twitter\lib\site-packages\rest_framework\response.py", line 70, in rendered_content
    ret = renderer.render(self.data, accepted_media_type, context)
  File "C:\Users\adilc\Desktop\twitter-vue-django\twitter\lib\site-packages\rest_framework\renderers.py", line 100, in render
    ret = json.dumps(
  File "C:\Users\adilc\Desktop\twitter-vue-django\twitter\lib\site-packages\rest_framework\utils\json.py", line 25, in dumps
    return json.dumps(*args, **kwargs)
  File "C:\Users\adilc\AppData\Local\Programs\Python\Python38\lib\json\__init__.py", line 234, in dumps
    return cls(
  File "C:\Users\adilc\AppData\Local\Programs\Python\Python38\lib\json\encoder.py", line 199, in encode
    chunks = self.iterencode(o, _one_shot=True)
  File "C:\Users\adilc\AppData\Local\Programs\Python\Python38\lib\json\encoder.py", line 257, in iterencode
    return _iterencode(o, 0)
  File "C:\Users\adilc\Desktop\twitter-vue-django\twitter\lib\site-packages\rest_framework\utils\encoders.py", line 50, in default
    return obj.decode()
UnicodeDecodeError: 'utf-8' codec can't decode byte 0xff in position 0: invalid start byte
如何在Rest框架上实现使用base64代码上传多个文件

views.py

class TweetCreateAPIView(APIView):

    def post(self, request):
        files = request.data.get('files')
        if files:
            files_list = []
            for file in files:
                file_data = file
                form, filestr = file_data.split(';base64,')
                ext = form.split('/')[-1]
                data = ContentFile(base64.b64decode(filestr), name='temp.'+ext)
                files_list.append(data)
            request.data.update({'files': files_list})

        
        serializer = TweetSerializer(data=request.data)
        if serializer.is_valid():
            serializer.save(user=request.user)
        print(serializer.errors)
        return Response(
            serializer.data,status=status.HTTP_201_CREATED
        )
序列化程序.py

class FileSerializer(serializers.ModelSerializer):
    file = serializers.FileField()
    class Meta:
        model = File
        fields = ('file',)

class TweetSerializer(serializers.ModelSerializer):
    likes = serializers.SerializerMethodField(read_only = True)
    files = FileSerializer(many=True, required=False)
    user = serializers.StringRelatedField(read_only=True)

    class Meta:
        model = Tweet
        fields = [
            'id',
            'user',
            'content',
            'likes',
            'files',
        ]

    def get_likes(self, obj):
        return obj.likes.count()
models.py

def upload_to(instance, filename):
    username = instance.post.user.username
    return '%s/%s/%s' %('TweetFiles', username, filename)

class CommonField(models.Model):
    content = models.TextField(null=False, blank=False)
    created_date = models.DateTimeField(auto_now_add = True)

    class Meta:
        abstract = True
        ordering = ['-created_date']

class Like(models.Model):
    user = models.ForeignKey(User,on_delete=models.CASCADE,related_name = 'likes')
    post = models.ForeignKey("Tweet",on_delete=models.CASCADE)
    created_date = models.DateTimeField(auto_now_add=True)

    def __str__(self):
        return self.user.username +" Liked "+ str(self.post.id)

class Tweet(CommonField):
    user = models.ForeignKey(User, related_name='tweets', on_delete=models.CASCADE, null=False, blank=False)
    likes = models.ManyToManyField(User,related_name='tweet_user', blank=True, through=Like)

class Comment(CommonField):
    user = models.ForeignKey(User, related_name='comments', on_delete=models.CASCADE, null=False, blank=False)

class File(models.Model):
    post = models.ForeignKey(to=Tweet, on_delete=models.CASCADE,related_name='files')
    file = models.FileField(upload_to=upload_to, null=True, blank=True)

TweetForm.vue(仅限数据和提交格式方法)

data(){
        return {
            tweet: '',
            files: [],
        }
    },
    methods: {
        submitForm(){
            const data = {
                'content': this.tweet,
                'files': this.files
            }
            axios.post('/api/add-tweet/', data)
            .then((result) => {
                console.log(result.data)
                this.tweet = ''
                this.files = []
                this.$store.commit('removeFiles')
            }).catch((err) => {
                console.log(err)
            });
        },