Register App myapp
devproject/settings.py
//devproject/settings.py
INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'myapp', #add myapp
]
Creating View myapp/views.py
//myapp/views.py
from django.shortcuts import render
from .forms import ImageForm
from django.http import JsonResponse
def index(request):
form = ImageForm(request.POST or None, request.FILES or None)
if form.is_valid():
form.save()
return JsonResponse({'message': 'works'})
context = {'form': form}
return render(request, 'main.html', context)
devproject/urls.py
//devproject/urls.py
from django.contrib import admin
from django.urls import path, include
from django.conf import settings
from django.conf.urls.static import static
urlpatterns = [
path('admin/', admin.site.urls),
path('', include('myapp.urls'))
]
urlpatterns += static(settings.STATIC_URL, document_root=settings.STATIC_ROOT)
urlpatterns += static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
myapp/urls.py
//myapp/urls.py
from django.urls import path
from . import views
urlpatterns = [
path('', views.index, name='index'),
]
Make Migrations Run the commands below to make migrations:
python manage.py makemigrations
python manage.py migrate
C:\django\devproject>python manage.py makemigrations
C:\django\devproject>python manage.py migrate
myapp/models.py
//myapp/models.py
from django.db import models
class Image(models.Model):
file = models.ImageField(upload_to='images')
uploaded = models.DateTimeField(auto_now_add=True)
def __str__(self):
return str(self.pk)
myapp/forms.py
//myapp/forms.py
from django import forms
from .models import Image
class ImageForm(forms.ModelForm):
class Meta:
model = Image
fields = ('file',)
Bootstrap 5 https://getbootstrap.com/docs/5.0/getting-started/introduction/
https://cdn.jsdelivr.net/npm/bootstrap@5.0.2/dist/css/bootstrap.min.css
Jquery
https://jquery.com/download/
CDN : jsDelivr CDN
https://www.jsdelivr.com/package/npm/jquery
https://cdn.jsdelivr.net/npm/jquery@3.6.0/dist/jquery.min.js
Cropper
A simple jQuery image cropping plugin.
https://fengyuanchen.github.io/cropper/
CDN : https://cdnjs.com/libraries/cropper
myapp/templates/home.html
//myapp/templates/home.html
{% extends 'base.html' %}
{% block content %}
<div class="container py-5">
<header class="text-white text-center">
<h1 class="display-4">Python Django Image Crop and Upload Crop Image with javascript ajax</h1>
</header>
<div class="row py-4">
<div class="col-lg-6 mx-auto">
<div class="input-group mb-3 px-4 py-2 rounded-pill bg-white shadow-sm">
<form action="" id="image-form" style="padding-top:10px;">
{% csrf_token %}
{{form.as_p}}
</form>
</div>
<div id="alert-box"></div>
<div class="image-area mb-3"><div id="image-box"></div></div>
<button class="btn btn-primary mt-3 not-visible" id="confirm-btn">Confirm</button>
</div>
</div>
</div>
<style>
#upload {
opacity: 0;
}
.image-area {
border: 2px dashed rgba(255, 255, 255, 0.7);
padding: 1rem;
}
body {
min-height: 100vh;
background-color: #7b9a75;
background-image: linear-gradient(147deg, #7b9a75 0%, #d7dde8 100%);
}
</style>
{% endblock content %}
myapp/templates/base.html
//myapp/templates/base.html
{% load static %}
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<link rel="shortcut icon" type="image/png" href="{% static 'favicon.ico' %}"/>
<link rel="stylesheet" type="text/css" href="https://cdn.jsdelivr.net/npm/bootstrap@5.0.2/dist/css/bootstrap.min.css"/>
<!-- jquery -->
<script src="https://cdn.jsdelivr.net/npm/jquery@3.6.0/dist/jquery.min.js"></script>
<!-- cropper -->
<script src="https://cdnjs.cloudflare.com/ajax/libs/cropper/4.1.0/cropper.min.js"></script>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/cropper/4.1.0/cropper.min.css">
<title>Python Django Image Crop and Upload Crop Image with javascript ajax</title>
<style>
.not-visible {
display: none;
}
</style>
</head>
<body>
<div class="container">
{% block content %}
{% endblock content %}
</div>
<script>
const alertBox = document.getElementById('alert-box')
const imageBox = document.getElementById('image-box')
const imageForm = document.getElementById('image-form')
const confirmBtn = document.getElementById('confirm-btn')
const input = document.getElementById('id_file')
const csrf = document.getElementsByName('csrfmiddlewaretoken')
input.addEventListener('change', ()=>{
alertBox.innerHTML = ""
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')
console.log($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);
}
});
var cropper = $image.data('cropper');
confirmBtn.addEventListener('click', ()=>{
cropper.getCroppedCanvas().toBlob((blob) => {
console.log('confirmed')
const fd = new FormData();
fd.append('csrfmiddlewaretoken', csrf[0].value)
fd.append('file', blob, 'my-image.png');
$.ajax({
type:'POST',
url: imageForm.action,
enctype: 'multipart/form-data',
data: fd,
success: function(response){
console.log('success', response)
alertBox.innerHTML = `<div class="alert alert-success" role="alert">
Successfully saved and cropped the selected image
</div>`
},
error: function(error){
console.log('error', error)
alertBox.innerHTML = `<div class="alert alert-danger" role="alert">
Ups...something went wrong
</div>`
},
cache: false,
contentType: false,
processData: false,
})
})
})
})
</script>
</body>
</html>
Run : C:\django\devsite>python manage.py runserver
