Как создать перетаскивание и пересылку в некоторую функцию в 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;
}
Вернуться на верх