Ajax 调用 Django 函数

Ajax call to Django function

我正在尝试删除通过 Ajax 通过复选框选择的图像列表,这些图像是通过 Django Ajax 上传器上传的。我已经成功获得了图像列表,但我不确定如何通过 Ajax 将其传递给 Django 函数。任何人都可以建议:

  1. 如何将所选图像列表传递给 Django 函数以删除图像?
  2. 我应该如何处理 ajax 部分的 CSRF?

html

<!DOCTYPE html>{% load static from staticfiles %} {% load i18n %}
<html lang="en">

<head>
  <meta charset="utf-8" />
  <meta name="viewport" content="width=device-width, initial-scale=1" />
  <title>Demo</title>
  <script src="{% static 'js/jquery.min.js' %}"></script>
  <!-- Latest compiled and minified JavaScript -->
  <script src="http://netdna.bootstrapcdn.com/bootstrap/3.1.1/js/bootstrap.min.js"></script>

  <!-- Latest compiled and minified CSS -->
  <link rel="stylesheet" href="http://netdna.bootstrapcdn.com/bootstrap/3.1.1/css/bootstrap.min.css" />
  <!-- Optional theme -->
  <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.1/css/bootstrap-theme.min.css">
  <style>
    input.chk {
      margin-left: 70px;
    }
  </style>
</head>

<body>
  <div class="wrapper">
    <div id="content" class="clearfix container">
      {% load i18n crispy_forms_tags %}
      <form method="post" action="." enctype="multipart/form-data">
        {% csrf_token %} {% crispy form %} {% crispy formset formset.form.helper %}
        <div class="image-upload-widget">
          <div class="preview">
          </div>
          <div class="file-uploader">
            <noscript>
              <p>{% trans "Please enable JavaScript to use file uploader." %}</p>
            </noscript>
          </div>
          <p class="help_text" class="help-block">
            {% trans "Available file formats are JPG, GIF and PNG." %}
          </p>
          <div class="messages"></div>
        </div>
        <input type="submit" name="save" class="btn btn-primary pull-right" value="Submit">
        <input type="button" id="delete" class="btn btn-primary pull-left" value="Delete Selected Files">
      </form>
    </div>
  </div>
  <script src="{% static 'js/fileuploader.js' %}"></script>
  <link href="{% static 'css/fileuploader.css' %}" media="screen" rel="stylesheet" type="text/css" />
  <script>
    $(function() {
      var uploader = new qq.FileUploader({
        action: "{% url 'planner:ajax_uploader' %}",
        element: $('.file-uploader')[0],
        multiple: true,

        onComplete: function(id, fileName, responseJSON) {
          if (responseJSON.success) {
            url = '<label for="' + fileName + '"><img src="' + {{MEDIA_URL}} + responseJSON.url + '" alt="" /></label>';
            checkbox = '<p><input type="checkbox" class="chk" id="' + fileName + '" name="' + fileName + '" value="0" /></p>';
            $('.preview').append(url);
            $('.preview').append(checkbox);
          } else {
            alert("upload failed!");
          }
        },
        onAllComplete: function(uploads) {
          // uploads is an array of maps
          // the maps look like this: {file: FileObject, response: JSONServerResponse}
          alert("All complete!");

          alert(checkbox);
        },
        params: {
          'csrf_token': '{{ csrf_token }}',
          'csrf_name': 'csrfmiddlewaretoken',
          'csrf_xname': 'X-CSRFToken',
        },
      });
    });
  </script>
  <script>
    $("#delete").on('click', function() {
      var allVals = [];

      $(":checkbox").each(function() {
        var ischecked = $(this).is(":checked");
        if (ischecked) {
          allVals.push(this.id);
        }
      });
    });
  </script>
</body>

</html>

获得要删除的图像列表后,将其传递给将由 Django 视图处理的 Ajax 调用,如下所示:

function submitData(data) {
    var csrftoken = getCookie('csrftoken'); // from https://docs.djangoproject.com/en/1.7/ref/contrib/csrf/#ajax 
    $.ajax({
        type: 'POST',
        beforeSend: function(xhr, settings) {
            if (!csrfSafeMethod(settings.type) && !this.crossDomain) {
                xhr.setRequestHeader("X-CSRFToken", csrftoken);
            }
        },
        data: JSON.stringify(data),
        url: {% url 'image_handler' %}
    }).done(function(data) {
        console.log(data.deleted + ' images were deleted');
    }).error(function(data) {
        console.log('errors happened: ' + data);
    });
}

然后,在你的 views.py:

def image_handler(request):
    if request.method != 'POST':
        return HttpResponseNotAllowed(['POST'])

    str_body = request.body.decode('utf-8')
    changes = json.loads(str_body)
    for change in changes:
        pass  # `change` contains the id of the image to delete
    data = {'status': 200,
            'deleted': len(changes)}
    return JsonResponse(data)

效果很好:)