ホームページ > バックエンド開発 > Python チュートリアル > python Django框架实现自定义表单提交

python Django框架实现自定义表单提交

WBOYWBOYWBOYWBOYWBOYWBOYWBOYWBOYWBOYWBOYWBOYWBOYWB
リリース: 2016-06-10 15:05:29
オリジナル
1596 人が閲覧しました

除了使用Django内置表单,有时往往我们需要自定义表单。对于自定义表单Post方式提交往往会带来由CSRF(跨站请求伪造)产生的错误"CSRF verification failed. Request aborted."

本篇文章主要针对"表单提交"和"Ajax提交"两种方式来解决CSRF带来的错误

一、表单提交
Template:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

<!DOCTYPE html>

<html lang="en">

<head>

  <meta charset="UTF-8">

  <title>计算数字和</title>

</head>

<body>

  <form method="post" action="{%url 'Calculate' %}">

    {% csrf_token %}

    <label for="A"><input id="A" name="ValueA" type="text"></label>

    <label for="B"><input id="B" name="ValueB" type="text"></label>

    <input type="submit" value="开始计算">

  </form>

</body>

</html>

ログイン後にコピー

Views.py:

1

2

3

4

5

6

7

8

def Calculate(request):

  if request.POST:

    a=request.POST["ValueA"]

    b=request.POST["ValueB"]

    c=str(int(a)+int(b))

    return render_to_response('Result.html',{'result':c})

  else:

    return render_to_response('Calculation.html',context_instance=RequestContext(request))

ログイン後にコピー

需要注意:

(1)在

标签内添加{% csrf_token %},这样在表单提交的过程中,会产生"csrfmiddlewaretoken"标识去防止CSRF

(2)在Get请求页面时,需要添加context_instance=RequestContext(request) ,它和{% csrf_token %}配合使用,缺少一个都会出现上述错误,RequestContext 需要在 django.shortcuts 导入

(3)只有当表单以Post方式提交时,才需要验证CSRF,Get方式是不需要的

二、Ajax提交
同比与表单提交,Ajax提交需要进行额外的操作,Ajax提交时需要自己提供"csrfmiddlewaretoken"标识参数。我们除了需要引入JQuery外还需要引入一段JS代码

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

jQuery(document).ajaxSend(function(event, xhr, settings) {

  function getCookie(name) {

    var cookieValue = null;

    if (document.cookie && document.cookie != '') {

      var cookies = document.cookie.split(';');

      for (var i = 0; i < cookies.length; i++) {

        var cookie = jQuery.trim(cookies[i]);

        // Does this cookie string begin with the name we want&#63;

        if (cookie.substring(0, name.length + 1) == (name + '=')) {

          cookieValue = decodeURIComponent(cookie.substring(name.length + 1));

          break;

        }

      }

    }

    return cookieValue;

  }

  function sameOrigin(url) {

    // url could be relative or scheme relative or absolute

    var host = document.location.host; // host + port

    var protocol = document.location.protocol;

    var sr_origin = '//' + host;

    var origin = protocol + sr_origin;

    // Allow absolute or scheme relative URLs to same origin

    return (url == origin || url.slice(0, origin.length + 1) == origin + '/') ||

      (url == sr_origin || url.slice(0, sr_origin.length + 1) == sr_origin + '/') ||

      // or any other URL that isn't scheme relative or absolute i.e relative.

      !(/^(\/\/|http:|https:).*/.test(url));

  }

  function safeMethod(method) {

    return (/^(GET|HEAD|OPTIONS|TRACE)$/.test(method));

  }

  

  if (!safeMethod(settings.type) && sameOrigin(settings.url)) {

    xhr.setRequestHeader("X-CSRFToken", getCookie('csrftoken'));

  }

});

ログイン後にコピー

Template:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

<!DOCTYPE html>

<html lang="en">

<head>

  <meta charset="UTF-8">

  <title>Ajax 提交</title>

  <script type="text/javascript" src="/static/jquery.js"></script>

  <script type="text/javascript">

    jQuery(document).ajaxSend(function(event, xhr, settings) {

  function getCookie(name) {

    var cookieValue = null;

    if (document.cookie && document.cookie != '') {

      var cookies = document.cookie.split(';');

      for (var i = 0; i < cookies.length; i++) {

        var cookie = jQuery.trim(cookies[i]);

        // Does this cookie string begin with the name we want&#63;

        if (cookie.substring(0, name.length + 1) == (name + '=')) {

          cookieValue = decodeURIComponent(cookie.substring(name.length + 1));

          break;

        }

      }

    }

    return cookieValue;

  }

  function sameOrigin(url) {

    // url could be relative or scheme relative or absolute

    var host = document.location.host; // host + port

    var protocol = document.location.protocol;

    var sr_origin = '//' + host;

    var origin = protocol + sr_origin;

    // Allow absolute or scheme relative URLs to same origin

    return (url == origin || url.slice(0, origin.length + 1) == origin + '/') ||

      (url == sr_origin || url.slice(0, sr_origin.length + 1) == sr_origin + '/') ||

      // or any other URL that isn't scheme relative or absolute i.e relative.

      !(/^(\/\/|http:|https:).*/.test(url));

  }

  function safeMethod(method) {

    return (/^(GET|HEAD|OPTIONS|TRACE)$/.test(method));

  }

  

  if (!safeMethod(settings.type) && sameOrigin(settings.url)) {

    xhr.setRequestHeader("X-CSRFToken", getCookie('csrftoken'));

  }

});

  </script>

  <script type="text/javascript">

    $(function(){

       $.ajaxSetup({

          data:{csrfmiddlewaretoken: '{{ csrf_token }}'}

        });

        $("#Comment").click(function(){

          $.post('{% url 'AjaxRequest' %}',{"a":$("#A").val(),"b":$("#B").val()},function(data){

            $("#result").html(data);

          });

        });

    });

  </script>

</head>

<body>

  <label for="A"><input id="A" name="ValueA" type="text"></label>

  <label for="B"><input id="B" name="ValueB" type="text"></label>

  <input type="button" id="Comment" value="开始计算">

  <h1>计算的结果为:<span id="result"></span></h1>

</body>

</html>

ログイン後にコピー

View.py:

1

2

3

4

5

6

7

8

def AjaxRequest(request):

  if request.POST:

    a =request.POST["a"]

    b=request.POST["b"]

    c=int(a)+int(b)

    return JsonResponse(c,safe=False)

  else:

    return render_to_response('AjaxDemo.html',context_instance=RequestContext(request))

ログイン後にコピー

需要注意:

(1)在使用引入的JS代码后,需要添加如下代码,这样JS就可以自动帮我们生成"csrfmiddlewaretoken"标识,接下来你就可以使用$.post()了

1

2

3

$.ajaxSetup({

          data:{csrfmiddlewaretoken: '{{ csrf_token }}'}

        });

ログイン後にコピー

(2)context_instance=RequestContext(request) 并不是必须的

(3)Get请求不需要以上操作,直接使用$.get()即可
注:本文使用的Django1.8.3版本进行测试。

以上就是本文的全部内容,希望对大家的学习有所帮助。

このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。
人気のチュートリアル
詳細>
最新のダウンロード
詳細>
ウェブエフェクト
公式サイト
サイト素材
フロントエンドテンプレート