Как создать перетаскивание и пересылку в некоторую функцию в django?
У меня есть сайт на django, и я хотел бы внедрить drag&drop в мою форму. Эта часть выглядит очень старой по сравнению с остальной частью сайта. Проблема в том, что я не знаю javascript, я пытался сделать это из учебников, но это не имеет никакого смысла. Не могли бы вы помочь мне найти простое решение для этого. Есть идеи, как сделать это с нулевым знанием js?
cal.py
def OnlyCAL(request):
if request.method == "POST":
form = DocumentForm(request.POST, request.FILES)
if form.is_valid():
output = io.BytesIO()
newdoc = request.FILES['docfile']
#pandas calculations
response = HttpResponse(
output, content_type='application/vnd.openxmlformats-officedocument.spreadsheetml.sheet')
response['Content-Disposition'] = 'attachment; filename=%s' % filename
return response
else:
form = DocumentForm()
return render(request, 'cal.html', { 'form': form, 'page_title':page_title })
cal.html
{% extends "base.html" %}
{% load static %}
{% block content %}
<form action="{% url "cal" %}" method="post" enctype="multipart/form-data" class="dropzone">
{% csrf_token %}
{{ message }}
<p>{{ form.non_field_errors }}</p>
<p>{{ form.docfile.label_tag }} {{ form.docfile.help_text }}</p>
<p>
{{ form.docfile.errors }}
{{ form.docfile }}
</p>
<p><input type="submit" value="Upload and Download!"/></p>
</form>
{% endblock content %}
urls.py
urlpatterns = [
path('', views.home, name='home'),
path('cal/', cal.OnlyCAL, name='cal'),
]
Мне пришлось сделать это для одного из моих проектов.
Взять, к примеру, Экзамен. Студенты должны были загрузить свой экзаменационный файл через систему dropbox. Поскольку я не знаю ваших моделей, надеюсь, вы сможете применить этот метод к своему проекту.
Сначала бэкэнд:
Backend
Форма была простой. Форма только с полем файла.
forms.py
class ExamFileForm(forms.ModelForm):
class Meta:
model= Exam
fields= ('file',)
Представление. простой FBV, который извлекает заголовок из вызова AJAX, чтобы получить id экзамена. Затем я ищу экземпляр Exam
, проверяю форму и сохраняю файл в этом экземпляре, затем возвращаю положительный JSON-ответ обратно на вызов AJAX. Else я возвращаю неудачный ответ.
views.py
from django.http import JsonResponse
def load_exam_file(request):
exam_id = dict(request.headers.copy()).pop('exam_id', None)
exam= Exam.objects.get(id=exam_id)
form = ExamFileForm(data=request.POST, files=request.FILES)
if form.is_valid():
exam.file = form.cleaned_data['file']
exam.save()
return JsonResponse({
'uploaded':True,
})
return JsonResponse({'uploaded':False})
Шаблон
html похож на ваш простой дизайн drag box, позволяющий пользователям опускать элемент внутрь.
HTML:
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
<form class="box" method="post" action="" enctype="multipart/form-data">
{% csrf_token %}
<div class="box__dragbox">
<div class="box__dragbox_background"></div>
<p class="box__dragtext jlrFontMediumBold">Drag files to upload here</p>
</div>
<div class="box__uploading">Uploading…</div>
<div class="box__success">Done!</div>
<div class="box__error">Error! <span></span>.</div>
</form>
JQuery, множество различных обработчиков событий для изменения поведения коробки по мере перетаскивания и удаления от нее. Основным событием является drop
, в котором, когда вы бросаете файл, создается AJAX вызов и отправляется обратно на бэкэнд для оценки (Это также приносит данные формы и id регистрируется в header
.
Примечание: Убедитесь, что вы передали id в шаблон. Например, я передал
exam_id
в args представления, затем вызвал {{ exam_id }} в заголовке
JQuery:
$(document).on("dragover", 'html', function(e) {
e.preventDefault();
e.stopPropagation();
});
$(document).on("drop", 'html', function(e) {
e.preventDefault();
e.stopPropagation();
});
// Drag enter
$(document).on('dragenter','.box__dragbox', function (e) {
e.stopPropagation();
e.preventDefault();
$(".box__dragtext").text("Drop here!");
$(".box__dragbox_background").css({'opacity':'1'})
});
// Drag over
$(document).on('dragover','.box__dragbox', function (e) {
e.stopPropagation();
e.preventDefault();
$(".box__dragtext").text("Drop here!");
$(".box__dragbox_background").css({'opacity':'1'})
});
$(document).on('dragleave','.box__dragbox', function (e) {
e.stopPropagation();
e.preventDefault();
$(".box__dragtext").text("Drag files to upload here");
$(".box__dragbox_background").css('opacity','0')
});
// Drop
$(document).on('drop','.box__dragbox', function (e) {
e.stopPropagation();
e.preventDefault();
$(".box__dragtext").text("Uploaded!");
var file = e.originalEvent.dataTransfer.files;
var fd = new FormData();
fd.append('file', file[0])
uploadData(fd);
});
function uploadData(formdata){
$.ajax({
type: 'POST',
headers: {'X-CSRFToken': $.cookie('csrftoken'),'id':{{ exam_id }},
url: window.location.href,
data: formdata,
success: function(response){
if (response.uploaded) {
console.log("Uploaded!");
}
else {
console.log("Did not upload :(")
}
},
async: false,
cache: false,
contentType: false,
processData: false,
});
}
CSS - это просто дизайн, который я создал для простого dropbox.
CSS:
.box__dragndrop,
.box__uploading,
.box__success,
.box__error {
display: none;
}
.box__dragbox_background {
background-color:#ebebeb;
opacity:0;
position: absolute;
width: 100%;
height: 100%;
transition:'opacity 0.5s ease-in-out'
}
.box__dragbox {
border: 3px dashed #c1c1c1;
height: 200px;
border-radius: 10px;
justify-content: center;
display: flex;
align-items: center;
position: relative;
}
.box__dragtext {
color: grey;
z-index: 1;
}