url反向解析

  在使用Django 项目时,一个常见的需求是获得URL 的最终形式,以用于嵌入到生成的内容中(视图中和显示给用户的URL等)或者用于处理服务器端的导航(重定向等)。

  人们强烈希望不要硬编码这些URL(费力、不可扩展且容易产生错误)或者设计一种与URLconf 毫不相关的专门的URL 生成机制,因为这样容易导致一定程度上产生过期的URL。

可以自动更新而不用遍历项目的源代码来搜索并替换过期的URL。

要获取一个URL,最初拥有的信息是负责处理它的视图的标识(例如名字),与查找正确的URL 的其它必要的信息如视图参数的类型(位置参数、关键字参数)和值。

你用你的URLconf填充它,然后可以双向使用它:

  • 根据用户/浏览器发起的URL 请求,它调用正确的Django 视图,并从URL 中提取它的参数需要的值。
  • 根据Django 视图的标识和将要传递给它的参数的值,获取与之关联的URL。

反向解析URL、反向URL匹配、反向URL查询或者简单的URL反查。

  在需要URL 的地方,对于不同层级,Django 提供不同的工具用于URL 反查:

  • url模板标签。
  • django.core.urlresolvers.reverse() 函数。
  • get_absolute_url() 方法。

  例子

  考虑一下URLconf:

from django.conf.urls import url

from . import views

urlpatterns = [
    #...
    url(r'^articles/([0-9]{4})/$', views.year_archive, name='news-year-archive'),
    #...
] 

/articles/nnnn/

  你可以在模板的代码中使用下面的方法获得它们:

<a href="{% url 'news-year-archive' 2012 %}">2012 Archive</a>

<ul>
{% for yearvar in year_list %}
<li><a href="{% url 'news-year-archive' yearvar %}">{{ yearvar }} Archive</a></li>
{% endfor %}
</ul>

  注意:上面的传参方式!!

  在python代码,可以这样使用:

from django.core.urlresolvers import reverse
from django.http import HttpResponseRedirect

def redirect_to_year(request):
    # ...
    year = 2006
    # ...
    return HttpResponseRedirect(reverse('news-year-archive', args=(year,)))# 注意传参方式

  对于这些情况,当反查URL 时,只有视图的名字还不够。

  URL模式的命名

comment,而另外一个应用中也有一个同样的名称,当你在模板中使用这个名称的时候不能保证将插入哪个URL。

comment

  反查带命名空间的URL

  当解析一个带命名空间的URL(例如'polls:index')时,Django 将切分名称为多个部分,然后按下面的步骤查找:

  1. 这将得到该应用实例的一个列表。

  2. current_app 属性。

  3. 'polls' 的实例)。

  4. 如果没有默认的应用实例,Django 将挑选该应用最后部署的实例,不管实例的名称是什么。

  5. 实例命名空间查找。

  6. 然后该视图的名称将被解析到找到的这个命名空间中的一个URL。

  例子:

    为了演示解析的策略,考虑教程中polls 应用的两个实例:'author-polls' 和'publisher-polls'

urls.py
from django.conf.urls import include, url

urlpatterns = [
    url(r'^author-polls/', include('polls.urls', namespace='author-polls', app_name='polls')),
    url(r'^publisher-polls/', include('polls.urls', namespace='publisher-polls', app_name='polls')),
]
polls/urls.py
from django.conf.urls import url

from . import views

urlpatterns = [
    url(r'^$', views.IndexView.as_view(), name='index'),
    url(r'^(?P<pk>\d+)/$', views.DetailView.as_view(), name='detail'),
    ...
]

  在模板中使用:

{% url 'polls:index' %}

跨站请求伪造保护

  使用规则

  1. 'django.middleware.csrf.CsrfViewMiddleware' 应该位于其它任何假设CSRF 已经处理过的视图中间件之前。

    csrf_protect()

  2. csrf_token 标签:

    <form action="." method="post">
    

    它不应该用于目标是外部URL 的POST 表单,因为这将引起CSRF 信息泄露而导致出现漏洞。

  3. 通常可以用两种方法实现:

  •  

  AJAX

这非常容易,因为许多JavaScript 框架都提供在每个请求上设置头部的方法。

csrftoken Cookie 中获取,如果你在视图中启用CSRF 防护它就会设置。

  注:

CSRF_COOKIE_NAME 设置自定义它的名字。

    获取token 非常简单:

// using jQuery
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?
            if (cookie.substring(0, name.length + 1) == (name + '=')) {
                cookieValue = decodeURIComponent(cookie.substring(name.length + 1));
                break;
            }
        }
    }
    return cookieValue;
}
var csrftoken = getCookie('csrftoken');

getCookie

);

function csrfSafeMethod(method) {
        return (/^(GET|HEAD|OPTIONS|TRACE)$/.test(method));
    }

    $.ajaxSetup({//全局设置csrf-token
       beforeSend:function (xhr,settings) {
           //请求头设置一次csrf-token
           if (!csrfSafeMethod(settings.type)){
               xhr.setRequestHeader('X-CSRFToken',$.cookie('csrftoken'));//在每次请求的cookie中设置csrftoken
           }
       }
    });
Jquery.cookie.js

相关文章: