AJAX-File-Uploader
Here is the link of the blog for this project, incase you want a code walk through.
Install django in your local machine if not installed.
pip install django
Run the project.
python manage.py runserver
This website collects cookies to deliver better user experience
django-admin startproject fileUploader
cd fileUploader
python manage.py runserver
python manage.py startapp uploader
from django.contrib import admin
from django.urls import path, include
urlpatterns = [
path('admin/', admin.site.urls),
path('fileUploader/', include('uploader.urls')),
]
INSTALLED_APPS = [
...
'uploader',
]
TEMPLATES = [
{
...
'DIRS': [os.path.join(BASE_DIR,'templates')],
...
}
]
STATIC_URL = '/static/'
STATICFILES_DIRS = [
os.path.join(BASE_DIR, 'static')
]
MEDIA_ROOT = os.path.join(BASE_DIR, 'media')
MEDIA_URL = '/media/'
{% 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="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.5.2/css/bootstrap.min.css"
integrity="sha384-JcKb8q3iqJ61gNV9KGb8thSsNjpSL0n8PARn9HuZOnIxN0hoP+VmmDGMN5t9UJ0Z" crossorigin="anonymous">
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/font-awesome/4.7.0/css/font-awesome.min.css"
crossorigin="anonymous">
<title>AJAX + DJANGO File Uploader</title>
<link rel="stylesheet" href="{% static 'css/app.css' %}">
</head>
<body>
<div class="col-lg-6 col-md-6" style="margin: 0 auto; display: block; margin-top: 100px;">
<form enctype="multipart/form-data" method="POST" action="">
{% csrf_token %}
<div class="form-group">
<label>Select file to upload.</label>
<input type="file" class="form-control" id="fileupload" placeholder="Select file">
</div>
<input type="submit" value="Upload" id="submit" class="btn btn-success">
</form>
<div id="uploaded_files"></div>
</div>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="{% static 'js/app.js' %}"></script>
</body>
</html>
#myProgress {
width: 100%;
}
#uploaded_files {
margin-top: 25px;
display: flex;
}
label {
font-weight: bold;
}
.file-icon i {
font-size: 60px;
color: rgb(0, 0, 0);
}
.file-details {
margin-top: -2px;
padding-left: 10px;
width: 100%;
}
.file-details p {
margin-bottom: -7px;
}
small {
margin-top: 0;
color: black;
}
class FileUpload {
constructor(input) {
this.input = input
this.max_length = 1024 * 1024 * 10; // 10 mb
}
upload() {
this.create_progress_bar();
this.initFileUpload();
}
initFileUpload() {
this.file = this.input.files[0];
this.upload_file(0, null);
}
(function ($) {
$('#submit').on('click', (event) => {
event.preventDefault();
var uploader = new FileUpload(document.querySelector('#fileupload'))
uploader.upload();
});
})(jQuery);
upload_file(start, path) {
var end;
var self = this;
var existingPath = path;
var formData = new FormData();
var nextChunk = start + this.max_length + 1;
var currentChunk = this.file.slice(start, nextChunk);
var uploadedChunk = start + currentChunk.size
if (uploadedChunk >= this.file.size) {
end = 1;
} else {
end = 0;
}
formData.append('file', currentChunk);
formData.append('filename', this.file.name);
formData.append('end', end);
formData.append('existingPath', existingPath);
formData.append('nextSlice', nextChunk);
$('.filename').text(this.file.name)
$('.textbox').text("Uploading file")
$.ajaxSetup({
// make sure to send the header
headers: {
"X-CSRFToken": document.querySelector('[name=csrfmiddlewaretoken]').value,
}
});
$.ajax({
xhr: function () {
var xhr = new XMLHttpRequest();
xhr.upload.addEventListener('progress', function (e) {
if (e.lengthComputable) {
if (self.file.size < self.max_length) {
var percent = Math.round((e.loaded / e.total) * 100);
} else {
var percent = Math.round((uploadedChunk / self.file.size) * 100);
}
$('.progress-bar').css('width', percent + '%')
$('.progress-bar').text(percent + '%')
}
});
return xhr;
},
url: '/fileUploader/',
type: 'POST',
dataType: 'json',
cache: false,
processData: false,
contentType: false,
data: formData,
error: function (xhr) {
alert(xhr.statusText);
},
success: function (res) {
if (nextChunk < self.file.size) {
// upload file in chunks
existingPath = res.existingPath
self.upload_file(nextChunk, existingPath);
} else {
// upload complete
$('.textbox').text(res.data);
alert(res.data)
}
}
});
};
create_progress_bar() {
var progress = `<div class="file-icon">
<i class="fa fa-file-o" aria-hidden="true"></i>
</div>
<div class="file-details">
<p class="filename"></p>
<small class="textbox"></small>
<div class="progress" style="margin-top: 5px;">
<div class="progress-bar bg-success" role="progressbar" aria-valuenow="0" aria-valuemin="0" aria-valuemax="100" style="width: 0%">
</div>
</div>
</div>`
document.getElementById('uploaded_files').innerHTML = progress
}
urlpatterns = [
path('', views.index, name='index'),
]
from django.shortcuts import render
from django.http import JsonResponse
import os
from .models import File
def index(request):
if request.method == 'POST':
file = request.FILES['file'].read()
fileName= request.POST['filename']
existingPath = request.POST['existingPath']
end = request.POST['end']
nextSlice = request.POST['nextSlice']
if file=="" or fileName=="" or existingPath=="" or end=="" or nextSlice=="":
res = JsonResponse({'data':'Invalid Request'})
return res
else:
if existingPath == 'null':
path = 'media/' + fileName
with open(path, 'wb+') as destination:
destination.write(file)
FileFolder = File()
FileFolder.existingPath = fileName
FileFolder.eof = end
FileFolder.name = fileName
FileFolder.save()
if int(end):
res = JsonResponse({'data':'Uploaded Successfully','existingPath': fileName})
else:
res = JsonResponse({'existingPath': fileName})
return res
else:
path = 'media/' + existingPath
model_id = File.objects.get(existingPath=existingPath)
if model_id.name == fileName:
if not model_id.eof:
with open(path, 'ab+') as destination:
destination.write(file)
if int(end):
model_id.eof = int(end)
model_id.save()
res = JsonResponse({'data':'Uploaded Successfully','existingPath':model_id.existingPath})
else:
res = JsonResponse({'existingPath':model_id.existingPath})
return res
else:
res = JsonResponse({'data':'EOF found. Invalid request'})
return res
else:
res = JsonResponse({'data':'No such file exists in the existingPath'})
return res
return render(request, 'index.html')
class File(models.Model):
existingPath = models.CharField(unique=True, max_length=100)
name = models.CharField(max_length=50)
eof = models.BooleanField()
python manage.py makemigrations
python manage.py migrate
Here is the link of the blog for this project, incase you want a code walk through.
pip install django
python manage.py runserver