Swift Загрузка изображения в Django Rest Framework

У меня есть Django 3.2 backend с Imagefield

протестировано на странице администратора работает нормально я могу загрузить изображение.

протестировано на Postman и работает нормально, я могу загрузить изображение.

когда я пытаюсь загрузить из swift, я получаю invalid_image

Я беру UIImage, конвертирую его с помощью pngData и отправляю в URLSession: param["src"] содержит UIImage

let paramSrc = param["src"] as! UIImage
if let fileData = paramSrc.pngData()?.base64EncodedString() {
       body += "; filename=\"myImg.png\"\r\n"
       body += "Content-Type: image/png\r\n\r\n\(fileData)\r\n"
                        
        }

Я также пробую без base64EncodedString, чтобы он был меньше по размеру, и все равно получаю ту же ошибку

Вот мой код для загрузки изображения с помощью alamofire

func uploadAvatar(img:UIImage){
    actionsObserver.onNext(.loading)
    
    let init_url = "http://********.***/api/users/add_profile_image"
    let userDefault = UserDefaults.standard
    let token = userDefault.string(forKey:"token") ?? ""
    let imgData = img.jpegData(compressionQuality: 0.7)!
    let hdr = HTTPHeader.init(name: "token", value: token)
    let header = HTTPHeaders.init([hdr])
    
    
    AF.upload(multipartFormData: { multipartFormData in
        multipartFormData.append(imgData, withName: "file",fileName: "file.jpg", mimeType: "image/jpg")
    }, to: init_url,headers: header)
        .responseJSON { response in
             // debugPrint(response)
            switch response.result {
            case .success(let json):
                print(json)
                let res = JSON(json)
                
                 let url = res["url"].stringValue
                    self.actionsObserver.onNext(.uploadAvatarSuccess(url: url))
                break
            case .failure( _):
                break
            }

        }

}

У меня была похожая проблема при загрузке изображения в REST Framework API и я решил ее :

views.py

from rest_framework.parsers import FormParser, MultiPartParser


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

    def put(self, request, format=None):
        instance = request.user
        serializer = ClassNameSerializer(instance, data=request.data)
        
        if not serializer.is_valid(raise_exception=True):
            return Response({
                "error": serializer.errors
            })
        serializer.save()

        return Response({
            "detail": "Model object updated",
        })

serializers.py


class ClassNameSerializer(serializers.ModelSerializer):

    class Meta:
        model = ClassName
        fields = ['profile_image', 'full_name', 'address', 'email', 'address']

    def update(self, instance, validated_data):

        if 'profile_image' in validated_data.keys():
            instance.profile_image = validated_data['profile_image']
        if 'full_name' in validated_data.keys():
            instance.full_name = validated_data['full_name']
        if 'email' in validated_data.keys():
            instance.email = validated_data['email'].lower()
        if 'address' in validated_data.keys():
            instance.address = validated_data['address']


        instance.save()
        return instance

Как вы видите, я не делал много работы с файлами в сериализаторах, так что в вашем случае добавьте это и попробуйте снова:

views.py

from rest_framework.parsers import FormParser, MultiPartParser

class PUser(APIView):
    parser_classes = (MultiPartParser, FormParser, )
    def patch(self, request, format=None):

Пожалуйста, попробуйте и посмотрите, работает ли это для вас.

Если у кого-то возникла такая же проблема, вот как я ее решил

Я просто меняю тело со строки на данные

var body = Data()

и тогда

 if let fileData = paramSrc.pngData() {
                        body.append("; filename=\"blah.png\"\r\n".data(using: .utf8)!)
                        body.append("Content-Type: \"content-type header\"\r\n\r\n".data(using: .utf8)!)
                        body.append(fileData)
                    }
Вернуться на верх