首页 > 解决方案 > 使 Django Data-Url 属性字符串形式在 .prepend 中工作

问题描述

我有一个 django web 应用程序 (esr_submit),它有一个表单和上传文件的能力。上传文件时(使用 fileupload jquery),上传文件列表需要通过 prepend 操作更新,复制 html 和 . 该按钮包含一个 data-url 属性,该属性调用 django url 及其各自的视图来完成删除操作。如何使 data-url 属性成为字符串以便脚本工作?

views.py

from django.shortcuts import render, redirect
from .forms import ServiceRequestForm, FileForm
from .models import RequestAttachment
from django.http import JsonResponse


def delete_file(request, pk):if request.method == 'POST':
        file = RequestAttachment.objects.get(pk=pk)
        file.delete()
    return redirect('/esr_submit/files')


def esr_submit(request):
    files = RequestAttachment.objects.all()
    if request.user.is_authenticated:
        initial_data = {'first_name': request.user.first_name,
                        'last_name': request.user.last_name,
                        'email': request.user.email,
                        'contact': request.user.phone,
                        }
        request_form = ServiceRequestForm(initial=initial_data)
    else:
        request_form = ServiceRequestForm()
    if request.method == 'POST':
        if 'submit_request' in request.POST:
            request_form = ServiceRequestForm(request.POST)
            if request_form.is_valid():
                request_form.save()
                return redirect('/esr_submit/')
            else:
                print(request_form.errors)
                return redirect('/esr_submit/')

        if 'file' in request.FILES:
            form = FileForm(request.POST, request.FILES)
            if form.is_valid():
                file = form.save()
                data = {'is_valid': True, 'name': file.file.name, 'url': file.file.url}
            else:
                data = {'is_valid': False}
            return JsonResponse(data)
        else:
            print("not a file form")
    else:
        files_list = RequestAttachment.objects.all()
        return render(request, 'esr_submit/esr_submit.html',
                      {'request_form': request_form,
                       'files': files,
                       'photos': files_list
                       }
                      )
urls.py

from django.urls import path
from . import views

urlpatterns = [
    path('', views.esr_submit, name='esr_submit'),
    path('files/', views.file_list, name='file_list'),
    path('files/<int:pk>/', views.delete_file, name='delete_file'),
esr_submit.html

{% extends "main/base.html" %}
{% block title %}
Submit an ESR
{% endblock %}
{% load crispy_forms_tags %}

{% block content %}
<head>

</head>
<br>
    <div class="container">
        <div class="row justify-content-md-center mb-2">
            <div class="col-sm-8 mb-4 shadow-lg p-3 bg-white rounded">
                <div class="header mb-2">
                    <h3 class="header mb-0 text-center">New Engineering Service Request</h3>
                    {% if not request.user.is_authenticated %}
                    <div class="text-center">
                        <small class="text-muted"><strong>Want to speed things up? </strong>
                            <a href="/login/?next=/esr_submit/"> Log In |</a>
                        </small>
                        <small class="text-muted">
                            <a href="/register/?next=/esr_submit/">Create an account </a>
                        </small>
                    </div>
                    {% endif %}
                </div>
                <form method="post" enctype="multipart/form-data" id="request_form"
                      class="request_form">
                    <div class="col">
                        {% csrf_token %}
                        {% crispy request_form %}
                        <span class="helper-text"></span>
                    </div>
                </form>
                <div class="container">
                    <button type="button" class="btn btn-primary js-upload-photos">
                    <span class="glyphicon glyphicon-cloud-upload"></span> Upload File(s)
                    </button>

                {# 2. FILE INPUT TO BE USED BY THE PLUG-IN #}
                    <form id="fileForm">
                      <input id="fileupload" type="file" name="file" class="file" multiple
                           style="display: none;"
                           data-url="{% url 'esr_submit:esr_submit' %}"
                           data-form-data='{"csrfmiddlewaretoken": "{{ csrf_token }}"}'>
                    </form>

                {# 3. TABLE TO DISPLAY THE UPLOADED FILES #}
                    <div id="myTable">
                        <table id="file-table" class="file-table table-borderless">
                          <thead>
                            <tr>
                                {% if photo in photos %}
                                <th>Attached Files</th>
                                {% else %}
                                {% endif %}
                            </tr>
                          </thead>
                          <tbody class="file-body">
                            {% for file in files %}
                              {% if file.file %}
                                <tr id="file-{{file.id}}"
                                    class="file">
                                    <td class="w-50">
                                      <a href="{{ file.file.url }}" target="_blank">{{ file.file }}</a>
                                    </td>
                                    <td class="delete" id="delete">
                                        <button type=submit data-id="file-{{file.id}}" data-url="{% url 'esr_submit:delete_file' file.pk %}" class="file-delete-btn btn btn-danger btn-sm">X</button>
                                    </td>
                                </tr>
                              {% else %}
                              {% endif %}
                            {% endfor %}
                          </tbody>
                        </table>
                    </div>
                </div>
                <div class="pl-2 mt-2">
                    <button type="submit" name="submit_request" value="submit_request" class="btn btn-primary" form="request_form">Submit Request</button>
                    <button type="submit" name="save_draft" value="save_draft" id="save_draft" class="btn btn-primary" form="request_form">Save Draft</button>
                </div>
            </div>
        </div>
    </div>
{% endblock content%}
script.js (loaded on the base.html)

/* Multiple File Upload Using AJAX - FROM SIMPLE IS BETTER THAN COMPLEX EXAMPLE */
$(function fileupload() {
  /* 1. OPEN THE FILE EXPLORER WINDOW */
  $(".js-upload-photos").click(function () {
    $("#fileupload").click();
  });

  /* 2. INITIALIZE THE FILE UPLOAD COMPONENT */
  $("#fileupload").fileupload({
    dataType: 'json',
    done: function (e, data) {  /* 3. PROCESS THE RESPONSE FROM THE SERVER */
      if (data.result.is_valid) {
        console.log(data)
        $("#file-table tbody").prepend(
          "<tr><td><a href='" + data.result.url + "' target='_blank'>" + data.result.name + "</a></td><td class='delete'><button type=submit data-id='file-{{file.id}}' data-url="{% url 'esr_submit:delete_file' file.pk %}" class='file-delete-btn btn btn-danger btn-sm'>X</button></td></tr>"
        )
      }
    }
  });
});


$('#myTable').on('click', '.file-delete-btn', function(e){
    e.preventDefault();

    var tableId = $(this).attr('file-table')
    var fileId = $(this).attr('data-id');
    var formAction = $(this).attr('data-url');

        $.ajax({
        url: formAction,
        method: 'POST',
        success: function(){
            $("#file-" + fileId).remove()
            console.log("file removed")
            $("#myTable").load(" #myTable");
        },
        error: function(errorData){
            console.log("error")
            console.log(errorData)
        }
        });

标签: javascriptjquerydjango

解决方案


{% url %}如果这是一个单独的文件,则不能在 Javascript 中使用该标签。如果您只有一个文件script.js,它将无法正常工作。

在这种情况下,您希望为删除部分生成正确的 URL。以最可靠的方式执行此操作的最佳方法(因此,如果您编辑 urls.py,它仍然可以工作)是使用 Django urlresolvers。然后将数据返回到您的上传过程。

在 Python 文件的顶部,放置以下内容:

from django.core.urlresolvers import reverse

POST 部分的最后一点esr_submit()可能如下所示:

        if 'file' in request.FILES:
            form = FileForm(request.POST, request.FILES)
            if form.is_valid():
                file = form.save()
                data = {'is_valid': True, 'name': file.file.name, 'url': file.file.url, 'file_id': file.id, 'remove_url': reverse('esr_submit:delete_file', args=[file.id])}
            else:
                data = {'is_valid': False}
            return JsonResponse(data)
        else:
            print("not a file form")

Javascript 位可能如下所示:

  /* 2. INITIALIZE THE FILE UPLOAD COMPONENT */
  $("#fileupload").fileupload({
    dataType: 'json',
    done: function (e, data) {  /* 3. PROCESS THE RESPONSE FROM THE SERVER */
      if (data.result.is_valid) {
        $("#file-table tbody").prepend(
          "<tr><td><a href='" + data.result.url + "' target='_blank'>" + data.result.name + "</a></td><td class='delete'><button type=submit data-id='file-" + data.result.file_id + "' data-url='" + data.result.remove_url + "' class='file-delete-btn btn btn-danger btn-sm'>X</button></td></tr>"
        )
      }
    }
  });

我没有让你的应用程序运行到这来自我的头顶。


推荐阅读