使用Django通过Ajax POST

时间:2015-11-22 01:54:02

标签: python ajax django post django-forms

基于https://godjango.com/18-basic-ajax/我通过Ajax和Django尝试POST。

我在GitHub上创建了一个项目https://github.com/rg3915/front-dj-test

urls.py

url(r'^customer/add$', 'core.views.customer_add', name='customer_add'),
url(r'^customer/save$', 'core.views.customer_save', name='customer_save'),

models.py

class Customer(models.Model):
    name = models.CharField(max_length=50)
    email = models.EmailField()

views.py

import json
from django.shortcuts import render
from django.http import Http404, HttpResponse


def customer_add(request):
    return render(request, 'customer_add.html')


def customer_save(request):
    if request.is_ajax() and request.POST:
        # return HttpResponse('Salvou')
        data = {'message': "%s added" % request.POST.get('item')}
        return HttpResponse(json.dumps(data), content_type='application/json')
    else:
        raise Http404

customer_add.html

<html>
  <body>
  <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/css/bootstrap.min.css">
  <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.3/jquery.min.js"></script>

  <form class="form-horizontal col-sm-4 col-lg-4" method="POST">
    <legend>Cadastrar</legend>
    {% csrf_token %}

    <div class="form-group">
      <label for="id_name">Nome</label>
      <input type="text" id="id_name" name="name" class="form-control">
    </div>

    <div class="form-group">
      <label for="id_email">e-mail</label>
      <input type="text" id="id_email" name="email" class="form-control">
    </div>

    <div class="form-group">
      <div class="col-sm-10 col-sm-offset-2">
      <button type="submit" id="id_submit" class="btn btn-primary">Salvar</button>
      </div>
    </div>
  </form>

  <script>
    $('form').submit(function(event) {
      console.log($( "form" ).serializeArray());
      $.ajax({
        type: 'POST',
        url: '/customer/save',
        data: {"item": $("input").val()},
        dataType: 'json',
        encode: true,
        crossDomain: false,
        beforeSend: function(xhr, settings) {
          if (!csrfSafeMethod(settings.type)) {
            xhr.setRequestHeader("X-CSRFToken", csrftoken);
          }
        },
        success: function(data){
          console.log(data);
        },
        error: function(){
          // alert('Deu Erro');
          console.log('Deu Erro');
        }
      });
      event.preventDefault();

      // CSRF code
      function getCookie(name) {
        var cookieValue = null;
        var i = 0;
        if (document.cookie && document.cookie !== '') {
          var cookies = document.cookie.split(';');
          for (i; i < cookies.length; i++) {
            var cookie = jQuery.trim(cookies[i]);
            // Does this cookie string begin with the name we want?
            if (cookie.substring(0, name.length + 1) === (name + '=')) {
              cookieValue = decodeURIComponent(cookie.substring(name.length + 1));
              break;
            }
          }
        }
        return cookieValue;
      }
      var csrftoken = getCookie('csrftoken');

      function csrfSafeMethod(method) {
        // these HTTP methods do not require CSRF protection
        return (/^(GET|HEAD|OPTIONS|TRACE)$/.test(method));
      }
    });
  </script>

  </body>
</html>

但是这会给出一些错误。见下图:

enter image description here

我想知道需要纠正什么来完美地完成所有事情。

2 个答案:

答案 0 :(得分:0)

你需要

from django.views.decorators.csrf import csrf_exempt

@csrf_exempt
def customer_save(request):
    # ...

答案 1 :(得分:0)

你做错了。您发送了未定义的crsftoken,因为您在请求后定义了crsftoken值:var csrftoken = getCookie('csrftoken');

纠正解决方案:

function getCookie(name) {
  var cookieValue = null;
  var i = 0;
  if (document.cookie && document.cookie !== '') {
    var cookies = document.cookie.split(';');
    for (i; i < cookies.length; i++) {
      var cookie = jQuery.trim(cookies[i]);
      // Does this cookie string begin with the name we want?
      if (cookie.substring(0, name.length + 1) === (name + '=')) {
        cookieValue = decodeURIComponent(cookie.substring(name.length + 1));
        break;
      }
    }
  }
  return cookieValue;
}
function csrfSafeMethod(method) {
    // these HTTP methods do not require CSRF protection
    return (/^(GET|HEAD|OPTIONS|TRACE)$/.test(method));
}
$('form').submit(function(event) {
    event.preventDefault();
    console.log($( "form" ).serializeArray());
    $.ajax({
        type: 'POST',
        url: '/customer/save',
        data: {"item": $("input").val()},
        dataType: 'json',
        encode: true,
        crossDomain: false,
        beforeSend: function(xhr, settings) {
            if (!csrfSafeMethod(settings.type)) {
                xhr.setRequestHeader("X-CSRFToken", getCookie('crsftoken'));
            }
        },
        success: function(data){
            console.log(data);
        },
        error: function(){
            // alert('Deu Erro');
            console.log('Deu Erro');
        }
    });
});

您还可以在data对象中发送CRSF令牌。您可以像其他字段一样处理crsftoken,然后您不再需要getCookie csrfSafeMethod个功能。这是一个例子:

// replace with the correct CSS selector of your crsftoken input
var crsftoken = $('input[name=\'crsftokenmiddleware\']').val()
$.ajax({
    type: 'POST',
    url: '/customer/save',
    data: {
      'crsftokenmiddleware': crsftoken
      'item': $("input").val()
    },
    dataType: 'json',
    encode: true,
    crossDomain: false,
    success: function(data){
        console.log(data);
    },
    error: function(){
        // alert('Deu Erro');
        console.log('Deu Erro');
    }
});