首页 > 解决方案 > “提交的数据不是文件。请检查表单上的编码类型。” RestFramework 中的错误

问题描述

我正在制作一个学生入学系统,我需要上传图片,当我上传图片时,我的 models.py 看起来像这样,

模型.py:

def scramble_uploaded_filename(instance, filename):
    extension = filename.split(".")[-1]
    return "{}.{}".format(uuid.uuid4(), extension)

class StudentAdmission(BaseModel):
    student = models.ForeignKey(Student,on_delete=models.CASCADE)
    admission_date = models.DateTimeField(auto_now_add=True)
    batch = models.IntegerField()
    course = models.ForeignKey(Course,on_delete=models.CASCADE)
    description = models.CharField(max_length=120)
    image = models.ImageField("Uploaded image", upload_to=scramble_uploaded_filename)

我在 serializers.py 中使用 planeSerializer imageField,如下所示:

序列化程序.py

class StudentAdmissionBaseSerializer(serializers.Serializer):
    user = UserSerializer()
    user_detail = UserDetailSerializer()
    phone_detail = PhoneSerializer()
    address_detail = AddressSerializer()
    registration_no = serializers.IntegerField()
    batch = serializers.IntegerField()
    description = serializers.CharField(default='')
    image = serializers.ImageField()

我的 views.py 看起来像这样:

视图.py:

class StudentAdmissionViewSet(viewsets.ModelViewSet):
    queryset = StudentAdmission.objects.all()
    serializer_class = StudentAdmissionSerializer
    parser_classes = (NestedMultipartParser,)



    def get(self, request):
        return Response([])
    def list(self, request):
        return Response([])

    def create(self,request):
        print({**request.POST,**request.FILES})
        serializer = self.get_serializer(data={**request.data,**request.FILES})


        if serializer.is_valid():
            data = serializer.data
            ud = data['user']

            user,b = User.objects.get_or_create(
                email=ud['email'],
                defaults={
                    'username':ud['email'],
                    'first_name':ud['first_name'],
                    'last_name':ud['last_name'],
                    'gender':ud['gender'],
                    'type':ud['type']
                    }
                )
            if not b:
                raise serializers.ValidationError({
                    'detail':["Email Already Exist"]
                    })



            c = ContentType.objects.get_for_model(user)
            Phone.objects.get_or_create(content_type=c,
                                        object_id=user.id,
                                        number=data['phone_detail']['number'],
                                        type=data['phone_detail']['type']
                                        )
            Address.objects.get_or_create(
                                        content_type=c,object_id=user.id,
                                        defaults={
                                        'province':data['address_detail']['province'],
                                        'district':data['address_detail']['district'],
                                        'city':data['address_detail']['city'],
                                        'address':data['address_detail']['address']
                                        }
                                        )

            detail = data.get('user_detail', False)
            if detail:
                UserDetail.objects.get_or_create(user_id=user.id,
                                                defaults={
                                                'blood_group':detail.get('blood_group',''),
                                                'nationality':detail.get('nationality',''),
                                                'mother_tongue':detail.get('mother_tongue',''),
                                                'religion':detail.get('religion',''),
                                                'citizenship_no':detail.get('citizenship_no',''),
                                                }
                                                )

            student,bval = Student.objects.get_or_create(user_id=user.id,registration_no=data['registration_no'])

            StudentAdmission.objects.get_or_create(student_id=student.id,
                                                   defaults={
                                                   'batch':data['batch'],
                                                   'course_id':data['course'],
                                                   'description':data['description'],
                                                   'image':data['image']
                                                   }
                                                   )

            return Response(data,status=status.HTTP_201_CREATED)

        else:
            raise serializers.ValidationError({
                    'detail':serializer.errors
                    })

在这里我写了一个 NestedMultipartParser 。这是我自己的解析器类。这个解析器类的完整代码如下所示:

from rest_framework import parsers

class NestedMultipartParser(parsers.MultiPartParser):

    def parse(self, stream, media_type=None, parser_context=None):

        result = super().parse(stream=stream, media_type=media_type, parser_context=parser_context)

        data = {}
        print(result.data)
        for key, value in result.data.items():
            if '.' in key:
                dict_key = key.split('.')
                nested_dict_key = dict_key[0]
                nested_value_key = dict_key[1]

                if nested_dict_key not in data:
                    data[nested_dict_key] = {}

                data[nested_dict_key][nested_value_key] = value 


                # if nested_value_key not in data:
                #   data[nested_dict_key] = {}
                #   data[nested_dict_key][nested_value_key] = value
                # else:
                #   data[key] = value
            else:
                data[key] = value
        return parsers.DataAndFiles(data,result.files)

这是我编写的所有代码,当我尝试通过表单上传图像时,它会引发错误

"image": [ "提交的数据不是文件。请检查表单上的编码类型。" ],

任何人都可以解释这种类型的错误吗?请任何开发人员都可以给我解决方案。谢谢!!!!

标签: pythondjangodjango-rest-framework

解决方案


推荐阅读