Django登陆装饰器及解析相关

登陆装饰器

有些页面是需要用户进行一些操作后才能进行访问的,直接访问是不被允许的,在这个情况下,如果将对应的验证操作全部定义在视图函数中,则会造成代码的冗余

解决方案:通过给需要操作的页面添加装饰器来达到验证的目的

1
2
3
4
5
6
7
8
9
10
11
12
13
14
# 先定义一个装饰器用户验证
def login_required(func):
def check_required(request, *args, **kwargs):
if request.session.has_key('login') and request.session['login']:
return func(request, *args, **kwargs)
else:
return redirect('/signin')
return check_required


# 然后用装饰器装饰必须登陆才能够查看的页面
@login_required
def chanage_pwd(request):
return render(request, 'User/change_pwd.html')

Django CSRF防御原理

  • django默认开启了csrf的防御,它利用的是中间件

    1
    2
    3
    4
    MIDDLEWARE = [
    # 开启了CSRF防御,但是其仅仅针对POST提交的方式
    'django.middleware.csrf.CsrfViewMiddleware',
    ]
  • 为了避免本网站提交时也被屏蔽掉,则需要在模板文件对应的表单内部添加模板标签:<!–0–>

    1
    2
    3
    4
    5
    6
    7
    <form method="post" action="/login_check">
    <!-- 需要在表单内部添加csrf_token的模板变量 -->
    {% csrf_token %}
    <label for="username">用户名</label><input type="text" name="username" id="username">
    <label for="pwssword">用户名</label><input type="password" name="password" id="username">
    <input type="submit" value="提交">
    </form>
  • Django CSRF防御原理

    1. 渲染模板文件的时候会在页面生成一个csrfmiddlewaretoken的隐藏域,里面有一个value和cookie的值一样
    2. 服务器同时交给浏览器一个名叫csrftoken的cookie信息
    3. 提交表单的时候,会将两个信息同时提交给服务器,服务器进行比对,当两个信息一致的时候则验证通过,反之失败

反向解析

模板文件

当某一个url配置的地址发生变化的时候,页面上使用反向解析生成的地址不需要变化。本质是根据url正则表达式配置动态生成的url,其使用方式如下:

  1. 在项目urls.py配置文件中,include时添加参数【namespace】

    1
    2
    3
    4
    5
    6
    7
    8
    9
    from django.contrib import admin
    from django.urls import path, include

    urlpatterns = [
    path('admin/', admin.site.urls),
    # 添加的namespace名称可以自定定,但一般是保持和应用的名称一致
    # include的第一个参数是导入的路由文件,和app的名称,第二个参数是取的别名
    path('', include(('User.urls', 'User'), namespace="User"))
    ]
  2. 在应用对应的urls.py配置文件中,添加参数【name】

    1
    2
    3
    4
    5
    6
    7
    from django.urls import path
    from User import views
    urlpatterns = [
    # django中include中第一个参数是一个元祖,
    # 元祖中第一个参数对应引用urls.py配置文件的位置,第二个参数指定其服务的应用名称
    path('shuai', views.index, name="signup")
    ]
  3. 在模板文件中使用反向解析生成动态链接

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    <!-- 无参数的反向解析 -->
    {# path('signup', views.signup, name='signup')#}
    <a href="{% url "User:signup" %}">外链接内容</a>

    <!-- url中带位置参数的反向解析, 则只需要在后面追加对应参数的名称即可-->
    {# re_path('signup/(\w+)/(\w+)', views.signup, name='signup'),#}
    <a href="{% url "User:signup" 'path' 'b' %}">外链接内容</a>

    <!-- url中关键字参数的反向解析,后面需要跟上关键字对应的值信息 -->
    {# re_path('signup/(?P<path>\w+)/(?P<name>\w+)', views.signup, name='signup') #}
    <a href="{% url "User:signup" path='path' name='b' %}">外链接内容</a>

视图文件

在视图中,我们也常需要使用重定向,重定向有时也需要迁移至动态生成的链接中,方法如下:

1
2
3
4
5
6
7
8
9
10
def login(request):
# 不带参数的动态重定向
url = reverse("User:signup")

# 带位置参数的动态重定向, 利用元祖传递位置参数
url = reverse("User:signup", args=('path', 'b'))

# 带关键字参数的动态重定向,利用字典传递参数
url = reverse("User:signup", kwargs={"path":"path", "name":"b"})
return redirect(url)