Django Обрезка изображений в inlineFormsetFactory с помощью cropper
Я пытаюсь сделать inline formset, в котором одно поле получает обрезанное изображение как один из параметров. Я уже делал обрезку с помощью некоторых руководств, но это работает только с одной моделью, когда я попытался преобразовать ее в inline formset, новое изображение сохраняется в необработанном виде - обрезка не применяется.
тут я использовал: https://blog.pyplane.com/blog/how-to-crop-images-in-django-with-javascript/
модели выглядят следующим образом:
class Product(models.Model):
name = models.CharField(max_length=200)
category = models.ForeignKey(Category, on_delete=models.CASCADE)
availability = models.IntegerField()
price = models.DecimalField(max_digits=5, decimal_places=2)
class Photo(models.Model):
file = models.ImageField(upload_to=getImageURL2, default="static/default.png")
uploaded = models.DateTimeField(auto_now_add=True)
product = models.ForeignKey(Product, on_delete=models.CASCADE, null=True, blank=True)
forms.py
class ProductForm(forms.ModelForm):
class Meta:
model = Product
fields='__all__'
class PhotoForm(forms.ModelForm):
class Meta:
model = Photo
fields = ('file',)
ProductPhotoInlineFormset = inlineformset_factory(
Product,
Photo,
fields=('file',),
form=PhotoForm,
extra=1,
can_delete=False,
)
view
def ProductCreateView(request):
context = {}
created_product = None
form = ProductForm()
if request.method == 'POST':
print(request.POST)
form = ProductForm(request.POST)
if form.is_valid():
created_product = form.save()
print("Successfully created new product: {}".format(created_product))
else:
print("form is not valid")
print(form.errors)
print(form.non_field_errors())
context['form'] = form
formset = ProductPhotoInlineFormset()
if request.method=='POST':
formset = ProductPhotoInlineFormset(request.POST or None, request.FILES or None, instance=created_product)
if formset.is_valid():
for f in formset:
imageset_obj = f.save()
print("Successfully created new imagest: {}".format(imageset_obj))
return JsonResponse({'message': 'works'})
else:
print(formset.errors)
print(formset.non_form_errors())
context['formset'] = formset
return render(request, "Ecommerce/create_product_test.html", context)
созданный шаблон:
{% extends 'base.html' %}
{% block content %}
<div id="alert-box">
</div>
<div id="image-box" class="mb-3">
</div>
<div id="image-box"></div>
<form method="POST" enctype="multipart/form-data" action="" id="image-form">
{{formset.management_form}}
{% csrf_token %}
{{form}}
{% for form in formset %}
{{form.as_p}}
{% endfor %}
<button class="btn btn-primary mt-3 not-visible" id="confirm-btn">confirm</button>
</form>
{% endblock content %}
js -- > связано с использованием в base.html
const alertBox = document.getElementById('alert-box')
const imageBox = document.getElementById('image-box')
const imageForm = document.getElementById('image-form')
const nameField = document.getElementById('id_name')
const categoryField = document.getElementById('id_category')
const availabilityField = document.getElementById('id_availability')
const priceField = document.getElementById('id_price')
const confirmBtn = document.getElementById('confirm-btn')
//const input = document.getElementById('id_file')
const input = document.getElementById('id_photo_set-0-file')
const csrf = document.getElementsByName('csrfmiddlewaretoken')
input.addEventListener('change', ()=>{
console.log("changed")
confirmBtn.classList.remove('not-visible')
const img_data = input.files[0]
const url = URL.createObjectURL(img_data)
imageBox.innerHTML = `<img src="${url}" id="image" width="700px">`
var $image = $('#image');
$image.cropper({
aspectRatio: 1 / 1,
crop: function(event){
console.log(event.detail.x);
console.log(event.detail.y);
console.log(event.detail.width);
console.log(event.detail.height);
console.log(event.detail.rotate);
console.log(event.detail.scaleX);
console.log(event.detail.scaleY);
}
});
var cropper = $image.data('cropper');
confirmBtn.addEventListener('click', ()=>{
cropper.getCroppedCanvas().toBlob((blob)=>{
console.log('confirmed')
console.log(blob)
const fd = new FormData()
fd.append('csrfmiddlewaretoken', csrf[0].value)
fd.append('file', blob, 'my-image.png') /// some issue here
//fd.append('name', nameField.value)
//fd.append('category', categoryField.value)
//fd.append('availability', availabilityField.value)
//fd.append('price', priceField.value)
//fd.append('photo_set-TOTAL_FORMS', '1')
//fd.append('photo_set-INITIAL_FORMS', '0')
$.ajax({
type:'POST',
url: imageForm.action,
enctype: 'multipart/form-data',
data: fd,
success: function(response){
console.log(response)
alertBox.innerHTML = fd.get('file')
},
error: function(error){
console.log(error)
},
cache: false,
contentType: false,
processData: false,
})
})
})
})
новые объекты продукта и изображения создаются правильно, но сохраненное изображение не обрезается. Оно в необработанном виде, как будто не использовался js. Что нужно изменить? Я предполагаю, что есть какая-то проблема с передачей файла в FormData в js, но я не знаю, как это исправить