Отправка изображения 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",
);