1

I am using https://github.com/fengyuanchen/cropper/blob/master/README.md as the cropper function. However, I want to submit field objects (in this case the title) and the cropped image. But I got an error on the admin. And of course, I have done the makemigrations and migrate before running the server

Error Picture

admin.py

from django.contrib import admin
from .models import Image
# Register your models here.
class ImageAdmin(admin.ModelAdmin):
    pass

admin.site.register(Image, ImageAdmin)

models.py

from django.db import models

# Create your models here.
class Image(models.Model):
    title = models.CharField(max_length=10)
    image = models.ImageField(upload_to='images')

    def __str__(self):
        return str(self.pk)

forms.py

from django import forms
from .models import Image

class ImageForm(forms.Form):
    image = forms.ImageField()
    title = forms.CharField(
        max_length=10, 
        widget=forms.TextInput(
            attrs={
                "class": "form-control", 
                "placeholder": "Title",
                }, 
                ),
                required=True
                )

views.py

from django.shortcuts import render, redirect

from .models import Image
from .forms import ImageForm
from django.http import JsonResponse
from django.http import HttpResponseRedirect



def main_view(request):

    form = ImageForm()


    if request.method == "POST":

        form = ImageForm(request.POST, request.FILES)
        if form.is_valid():

                addimage = Image(
                    title=form.cleaned_data['title'],
                    image = form.cleaned_data['image'], 
                )

                addimage.save()
    else:
        form = ImageForm()
    context = {'form': form}
    return render(request, 'photo_list.html', context)

photo_list.html

{% extends "base.html" %}

{% block javascript %}
<script>
  console.log("Hello");
  const imageBox = document.getElementById("image-box");
  const confirmButton = document.getElementById("confirm-button")
  const input = document.getElementById("id_image");
  const csrf = document.getElementsByName("csrfmiddlewaretoken")
  const imageForm = document.getElementById("image-form")

  input.addEventListener("change", () => {
    console.log("change")

    const img_data = input.files[0]
    const url = URL.createObjectURL(img_data)

    imageBox.innerHTML = `<img src="${url}" id="image" width="500px">`

    var $image = $('#image');

    $image.cropper({
      aspectRatio: 16 / 9,
      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);
      }
    });

    // Get the Cropper.js instance after initialized
    var cropper = $image.data('cropper');

    confirmButton.addEventListener('click', () => {
      cropper.getCroppedCanvas().toBlob((blob) => {
        const fd = new FormData()
        fd.append('csrfmiddlewaretoken', csrf[0].value)
        fd.append('image', blob, 'my-image.png')
        console.log("append pass")


        $.ajax({
          type: "POST",
          url: imageForm.action,
          enctype: 'multipart/form-data',
          data: fd,
          success: function (response) {
            console.log(response)
          },
          error: function (error) {
            console.log(error)
          },
          cache: false,
          contentType: false,
          processData: false,
        })
      })
    })


  });
</script>
{% endblock %}

{% block page_content %}
<form action="/cropimage/" id="image-form" method="POST">
  {% csrf_token %}
  {{form}}
  {% comment %} <button class="btn" id="confirm-button"> confirm </button> {% endcomment %}
  <input class="btn btn-lg btn-primary btn-block" type="submit" value="Submit" id="confirm-button">
</form>
<div id="image-box" class="mb-3"> </div>

{% endblock %}

I was following this tutorial https://www.youtube.com/watch?v=oWd7SAuCIRM Basically, I am making an album of images recorded with title, but this time with cropperjs. Any solutions or suggestions would be appreciated :).

Andreas
  • 11
  • 1
  • 3
  • Another twist : I added default in my the models, title = models.CharField(max_length=10, default='"'), turning out no data on my databse when submit altered. – Andreas Apr 09 '21 at 07:39
  • Welcome to stackoverflow. Please avoid posting pictures of the issue and instead descripe it or paste the shown code in a stack snippet. The question should be understandable even when the url of the image has vanished. By the way you can edit your question - so there is no need to comment it... – biberman Apr 09 '21 at 08:31

1 Answers1

0

Ahh silly me, after a week of finding solutions, I finally realize that I did not put and after deleting some of the database cache.

fd.append('title', $("input[name='title']").val())

on the getCroppedCanvas()

For those who had the same problem, please.. Ref :

  1. How to append more data in FormData for django?
  2. OperationalError, no such column. Django
  3. https://developer.mozilla.org/en-US/docs/Web/API/FormData/append
Andreas
  • 11
  • 1
  • 3