Templates

模板

模板的功能:产生html,控制页面上展示的内容。模板文件不仅仅是一个html文件。

模板文件包含两部分内容:

1.静态内容:css,js,html

2.动态内容:用于动态去产生一些网页内容,通过模板语言来产生

1、模板文件的使用:通常是在视图函数中使用模板产生html内容返回给客户端

1.加载模板文件 loader.get_template(模板文件路径)-->获取模板文件的内容,产生一个模板对象

2.定义模板上下文 ResponseContext-->给模板文件传递数据

3.模板渲染产生html页面内容 render-->用传递的数据替换相应的变量,产生一个替换后的表中html内容

 render里面已经封装了上面这些步骤

render和redirect的返回值是HttpResponse的对象,本身是函数

创建django项目-->创建app-->配置settings app、模板配置、配置mysql数据库、init导入pymysql-->创建templates文件夹-->定义views-->配置url

 

模板文件加载过程

先去配置的模板目录下查找(BASE_DIR);去INSTALLED_APPS下面的每个应用去找模板文件,前提是应用中必须有templates文件夹

 

2、模板语言:DTL,Django Template Language

模板变量:模板变量名是由数字,字母,下划线和点组成的,不能以下划线开头

使用模板变量:{{模板变量名}}

模板变量的解析顺序:

例如:{{book.btitle}}

1.首先把book当成一个字典,把btitle当成键名,进行取值book['btitle']

2.把book当成一个对象,把btitle当成属性,进行取值book.btitle

3.把book当成一个对象,把btitle当成对象的方法,进行取值book.btitle

例如:{{book.0}}

1.首先把book当成一个字典,把0当成键名,进行取值book['0']

2.把book当成一个列表,把0当成下标,进行取值book[0]

如果解析失败,则产生内容时用空字符串填充模板变量

使用模板变量时,前面的可能是字典、对象、列表

 

模板标签

{%代码段%}

for循环:

{%for x in 列表%}

#列表不为空时执行

{% empty %}

#列表为空时执行

{% endfor %}

可以通过{{ forloop.counter}}得到for循环遍历到了第几次

{% if 条件 %}

{% elif 条件 %}

{% else %}

{% endif %}

关系比较操作符: > < >= <= == !=

注意:进行比较操作时,比较操作符两边必须有空格

逻辑运算:not and or

 

过滤器:过滤器用于对模板变量进行操作

date:改变日期的显示格式  date|date:'Y年-m月-d日'

length:求长度,字符串、列表 {{value|length}}

default:设置模板变量的默认值 {{value|default:'ha'}}前面判断为假使用后面变量

格式:模板变量 | 过滤器:参数

 

自定义过滤器:只能有一个参数或者两个参数,一个参数时候不用传参数,两个参数时需要传一个参数

templatetags(在目录下新建的一个包)中定义

#过滤器本质就是python函数

from django.template import Library

#创建一个Library类的对象

register=Library()

@register.filter

def mod(num):

  return num%2 == 0

-->{%load 文件名字%}

  {if book.id|mod}

{% load filters%}  #使用
<head></head>
<body></body>

模板注释

单行注释:{# 注释内容 #}

多行注释:{% comment %}

      注释内容

     {% endcomment %}

 

模板继承

 

在父模板里可以定义块,使用标签:

{% block 块名 %}

块中间可以写内容,也可以不写 

{% endblock 块名 %}

子模板去继承父模板之后,可以重写父模板中的某一块的内容

继承格式:{% extends 父模板文件路径 %}

{% block 块名 %}

{{ block.super }}#获取父模板中块的默认内容

重写的内容

{% endblock 块名 %}

 

{% block title %}

{% endblock title %}

 

把所有页面相同的内容放到父模板文件中,不需要放在块中。有些位置页面内容不同,需要在父模板中预留块。

 

html转义

在模板上下文中的html标记默认是会被转义的

小于号<  转换为&lt

大于号> 转换为&gt

单引号' 转换为&#39

双引号" 转换为&quot

与符号& 转换为&amp

要关闭模板上下文字符串的转义:可以使用{{模板变量|safe}}

也可以使用:

{% autoscape off %}模板语言代码

{% endautoescape %}

模板硬编码中的字符串默认不会经过转义,如果需要转义,那需要手动进行转义

硬编码:{{test|default:'<h1>Hello</h1>'}}

手动进行转义 {{test|default:&lth1&gtHello&lt/h1&gt}}

 

登录装饰器

在进行网站开发的时候,有些页面是用户登陆之后才能访问的,假如用户访问了这个地址,需要进行登录的判断,如果用户登录的话,可以进行后续的操作,如果没有登录,跳转到登录页

有些页面访问时要先判断是否登录

def login_required(view_func):
    '''登录判断装饰器'''
    def wrapper(request, *view_args, **view_kwargs):
        # 判断用户是否登录
        if request.session.has_key('islogin'):
            #用户已登录,调用对应的视图
            return view_func(request, *view_args, **view_kwargs)
        else:
                #用户未登录,跳转到登录页
                return redirect('/login')
    return wrapper

3、csrf攻击

首先做一个登录页,让用户输入用户名和密码进行登录,登录成功之后跳转到修改密码页面。在修改页面编辑内容,点击确认按钮完成密码修改。登录页需要一个模板文件login.html,修改密码页面也需要一个模板文件change_pwd.html。显示登录页的视图login,验证登录的视图login_check,显示发帖页的视图change_pwd,处理修改密码的视图change_pwd_action

 

 

1.登陆正常网站之后,浏览器保存的sessionid,没有退出

2.不小心访问了另外一个网站,并且点击了页面上的按钮,这个按钮点了之后是访问之前的网站,并且这个按钮中隐藏了其他提交信息

 

django默认启用了csrf保护,只针对post提交

表单post提交数据时加上{% csrf_token %}标签

MIDDLEWARE_CLASSES=(
......
'django.middleware.csrf.CsrfViewMiddleware',
......
)

原理:在表单里面加上{%csrf_token%}

<form method="post" action="/login_check">
    {% csrf_token %}
    ......
</form>

防御原理:

1.渲染模板文件时在页面生成一个名字叫做csrfmiddlewaretoken的隐藏域  这个隐藏域由{%csrf_token%}生成

2.服务器交给浏览器保存一个名字为csrftoken的cookie信息

3.提交表单时,两个值都会发给服务器,服务器进行比对,如果一样,则csrf验证通过,否则失败

第三方网站虽然把2中的cookie发过去了,但并没有隐藏域。

4、验证码

在用户注册、登录页面,为了防止暴力请求,可以加入验证码功能,如果验证码错误,则不需要继续处理,可以减轻业务服务器、数据库服务器的压力。

存到session?  Redis?

后台生成-->发给html显示-->提交表单-->后台取数据-->验证

5、反向解析

比如返回首页按钮

当某一个url配置的地址发生变化时,页面上使用反向解析生成地址的位置不需要发生变化

作用:根据url正则表达式的配置动态的生成url

使用:在项目urls中包含具体应用的urls文件时指定namespace

           再应用的urls中配置指定的name

urlpatterns={

  url(r'^admin/', include(admin.site.urls)),

  url(r'^', include('booktest.urls', namespace='booktest'))

}

在应用的urls中配置时指定name:

urlpatterns={

url(r'', views.index, name='index')

}

#urls.py
urlpatterns = [
    url(r'^show_args/(d+)(d+)$', views.show_args, name='show_args'),  #捕获位置参数
    url(r'^show_kwargs/(?P<c>d+)(?P<d>d+)$', views.show_kwargs, name='show_kwargs'),  #捕获关键字参数
]

#views.py
def show_args(request):
    pass

def show_kwargs(request, c, d):
    return HttpResponse(c+":"+d)
#视图中使用反向解析
from django.core.urlresolvers import reverse
def test_redirect(request):
    #url = reverse('booktese:index')
    #url = reverse('booktest:show_args', args=(1, 2))
    url = reverse('booktest:show_kwargs', kwargs={'c':3, 'd':4})
    return redirect(url)

 

原文地址:https://www.cnblogs.com/liushoudong/p/12799472.html