Отправка изображения Uint8List из Flutter в Django ImageField

Добрый день. У меня есть изображение подписи, я использую подпись: ^5.0.1 для Flutter. Мне нужно сохранить его в ImageField. Я не смог сохранить его в Django.

вот мой код внутри flutter

signaturePic(String imgName, SignatureController controller)async{
  String completeUrl = '$rootApi/reports/signature_pic/';
  var uri = Uri.parse(completeUrl);
  var request = http.MultipartRequest("POST", uri);
  Uint8List? signatureFile = await controller.toPngBytes();    
  if (signatureFile != null){
    final multipartFile = http.MultipartFile.fromBytes(imgName, signatureFile);
    request.files.add(multipartFile);
    request.headers["authorization"]='TOKEN ${temp.apiKey}';
  }
}

в Django 4.0 я использую djangorestframework==3.13.1

class SignaturePicView(APIView):
    def post(self, request):
        try:
            for title, value in request.data.items():
                items = title.split('__')
                is_return = True if items[5] == 'True' else False

                SignaturePic.objects.update_or_create(
                    user=User.objects.get(id=request.user.id),
                    unique_identifier=title,
                    is_return=is_return,
                    defaults={
                        'image': value,
                    }
                )
            return Response(status=status.HTTP_201_CREATED)

        except ValueError as e:
            print(e)
            return Response(status=status.HTTP_400_BAD_REQUEST, data=e)

это модель в django

class SignaturePic(models.Model):
    user = models.ForeignKey(User, on_delete=models.CASCADE)
    date_created = models.DateTimeField(auto_now_add=True)
    date = models.DateField(auto_now_add=True)
    unique_identifier = models.CharField(max_length=220, null=True, blank=True)
    image = models.ImageField(upload_to='signatures/', null=True, blank=True)
    is_return = models.BooleanField(default=False)

    def __str__(self):
        return f"{self.unique_identifier} -> {self.date}"

Когда он сохраняет, вот что я получаю.

Любая помощь будет высоко оценена. best,

Вам нужно отправить его как файл из frontend. А в бэкенде вы можете создать форму для обработки отправленного файла и сделать любую валидацию, если хотите. Ниже приведен рабочий код бэкенда. Фронтенд я не знаю о flutter, поэтому добавляю фрагмент react js, который вы можете использовать в качестве ссылки.

Backend :

forms.py

from django import forms

def validate_img_format(input_file):
    # Just an example. here you can add any validation if you have 
    # Or remove validate_img_format from ImageForm and just keep label
    if not input_file.name.endswith(".png"):
        raise forms.ValidationError("Only PNG file is accepted")

class ImageForm(forms.Form):
    imgfile = forms.FileField(label='signature image', validate_img_format)

Views.py

import ImageForm from './forms.py'

class SignaturePicView(APIView):
    def post(self, request):
        try:
            form = ImageForm(request.POST, request.FILES)
            if form.is_valid():
                # All your conditional checks
                sig_instance = SignaturePic(docfile = request.FILES['imgfile'])
                sig_instance.unique_identifier=title
                ...
                sig_instance.save()
            return Response(status=status.HTTP_201_CREATED)

        except ValueError as e:
            print(e)
            return Response(status=status.HTTP_400_BAD_REQUEST, data=e)

Frontend :

const async function FileUpload(e) {
    
const formData = new FormData();
formData.append("title", 'user entered title');
formData.append("imgfile", e.target.files[0]);
// all other fields
...

await axios({
    method: "post",
    headers: 'headers',
    url: 'url',
    data: formData,
  }).then().catch()

}

set contentType to 'application/json'

var file = http.MultipartFile.fromBytes(
    key,
    uint8listBytes,
    contentType: MediaType('application', 'json'),
    filename: "Name",
);
Вернуться на верх