一、创建应用test2并配置
1、创建应用
2、修改settings.xml配置信息
3、在应用下创建urls.py,在test2下的urls.py中引入urls.py
from django.conf.urls import include, url from django.contrib import admin urlpatterns = [ url(r'^admin/', include(admin.site.urls)), url(r'^', include('booktest.urls')), # 包含应用中的urls.py文件· ]
from django.conf.urls import include, url from booktest import views urlpatterns = [ url(r'^index/$', views.index), # 访问首页的url ]
4、在__init__.py中引入mysqldb
5、在models.py中创建图书模型类
from django.db import models # Create your models here. # 创建图书类 class BookInfo(models.Model): """图书模型类""" # 如果属性和数据库表的字段名称不一样时,用db_column进行映射 bittle = models.CharField(max_length=20, db_column='bittle') bpub_date = modles.DateField(db_column='bpud_date') bread = models.IntegerField(default=0) bcomment = models.IntegerField(default=0) isDelete = models.BooleanField(default=0) # 如果模型名称和表名不一样是,使用如下方式进行映射 class Meta: db_table = 'bookinfo'
6、在views.py中使用自定义render方法渲染模版
from django.shortcuts import render from django.template import loader,RequestContext from django.http import HttpResponse from booktest.models import * # Create your views here. # 自定义my_render方法 def my_render(request, template_path, context_dict): # 1.加载模版文件 temp = loader.get_template(template_path) # 2.定义模版上下文 context = RequestContext(request, context_dict) # 3.渲染模版 res_html = temp.render(context) # 4.返回数据给浏览器 return HttpResponse(res_html) # 访问首页的view def index(request): """使用自定义render方法进行渲染""" return my_render(request, 'booktest/index.html', {'content': 'hello'}
二、模版语言
1、模版变量
(1)、变量的定义
模板变量的作用是计算并输出,变量名必须由字母、数字、下划线(不能以下划线开头)和点组成。语法如下:
{{ 变量名称 }}
注意:当模版引擎遇到点如 {{book.title}},会按照下列顺序解析:
①、首先把book当成一个字典,把title当成键名,进行取值:book['title']
②、先属性后方法,把book当成一个对象,把title当成属性,进行取值book.title;如果没有title属性,把title当成对象的方法,进行取值book.title
③、如果是格式为{{book.0}},首先把book当成一个字典,把0当成键名,进行取值book['0'],如果没有为0的键名,把book当成一个列表,把0当成下标,进行取值book[0]
另:如果变量不存在则插入空字符串''。在模板中调用方法时不能传递参数。
(2)、变量应用示例
在views.py中创建视图方法temp_var
# 访问首页的view def index(request): """使用自定义render方法进行渲染""" return my_render(request, 'booktest/index.html', {'content': 'hello'}) # 模版变量视图 def temp_var(request): dict = {'title': '字典的值'} book = BookInfo() book.btitle = '对象属性' context = {'dict': dict, 'book': book} return my_render(request, 'booktest/temp_var.html', context)
配置url
# 配置模版变量的视图url url(r'^temp_var/$', views.temp_var),
创建temp_var.html模版
<html> <head> <title>模板变量</title> </head> <body> 模板变量:<br/> {{dict.title}}<br/> {{book.btitle}}<br/> </body> </html>
2、模版标签
(1)、标签语法如下:
{% 代码段 %}
(2)、for标签语法如下:
{%for item in 列表变量%} 循环逻辑表示循环列表,将每次循环得到的值放入item变量中 {{forloop.counter}} 表示当前是第几次循环,数值从1开始 {%empty%} 列表为空或不存在时执行此后的逻辑 {%endfor%} 列表循环结束的标志
(3)、if标签语法如下:
{%if 逻辑1%} 逻辑1条件成立下执行的代码 {%elif 逻辑2%} 逻辑2条件成立下执行的代码 {%else%} 逻辑3条件成立下执行的代码 {%endif%}
(4)、运算符
比较运算符: == != < > <= >=
布尔运算符:and or not
注意:运算符左右两侧必须要有空格
(5)、模版标签代码示例
views.py
# 模版标签视图 def temp_targ(request): """模版标签视图""" books = BookInfo.objects.all() context = {'books': books} return my_render(request, 'booktest/temp_targ.html', context)
urls.py
# 配置模版标签的视图url url(r'^temp_targ/$', views.temp_targ),
temp_targ.html
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>模版标签</title> <style> .red { background-color: red; } .yellow { background-color: yellow; } .green { background-color: green; } </style> </head> <body> <ul> {% for book in books %} {% if book.id <= 2 and book.bread > 12 %} <li class="red">{{ book.btitle }} -- {{ book.bpub_date }}</li> {% elif book.id <= 4 %} <li class="yellow">{{ book.btitle }} -- {{ book.bpub_date }}</li> {% else %} <li class="green">{{ book.btitle }} -- {{ book.bpub_date }}</li> {% endif %} {% endfor %} </ul> </body> </html>
3、过滤器
(1)、过滤器语法
使用管道符号|来应用过滤器,用于进行计算、转换操作,可以使用在变量、标签中。如果过滤器需要参数,则使用冒号:传递参数。
变量|过滤器:参数
长度length,返回字符串包含字符的个数,或列表、元组、字典的元素个数。默认值default,如果变量不存在时则返回默认值。
data|default:'默认值'
日期date,用于对日期类型的值进行字符串格式化,常用的格式化字符如下:
Y表示年,格式为4位,y表示两位的年。
m表示月,格式为01,02,12等。
d表示日, 格式为01,02等。
j表示日,格式为1,2等。
H表示时,24进制,h表示12进制的时。
i表示分,为0-59。
s表示秒,为0-59。
(2)、过滤器示例
temp_fileter.html
4、自定义过滤器
注意:自定义过滤器最多只能有两个参数,至少有一个参数
(1)、在应用下创建文件夹templatetags,文件夹中编写自定义过滤器filters.py以及空文件__init__.py
# 导入Library类 from django.template import Library # 创建一个Library类对象 register = Library() # 自定义过滤器 @register.filter def mod(num): """ 判断num是否为偶数 """ return num % 2 == 0 # 自定义过滤器,两个参数的 @register.filter def mod_val(num, val): """ 判断num能否被val整除 """ return num % val == 0
(2)、创建模版文件temp_filters.html
<!DOCTYPE html> <html lang="en"> {# 使用自定义过滤器要用load关键字,后面跟自定义过滤器的文件名 #} {% load filters %} <head> <meta charset="UTF-8"> <title>模板过滤器</title> <style> .red { background-color: red; } .yellow { background-color: yellow; } .green { background-color: green; } </style> </head> <body> <ul> {% for book in books %} {% if book.id|mod %} {# 使用带有一个参数的过滤器,不需要传参,过滤器默认将|之前的结果当作第一个参数 #} <li class="red">{{ book.btitle }}--{{ book.bpub_date|date:'y年-m月-d日' }}</li> {% else %} <li class="green">{{ book.btitle }}--{{ book.bpub_date }}</li> {% endif %} {% endfor %} </ul> <hr> <ul> {% for book in books %} {% if book.id|mod_val:3 %} {# 使用带有两个参数的过滤器,需要给第二个参数传值 #} <li class="red">{{ book.btitle }}--{{ book.bpub_date|date:'y年-m月-d日' }}</li> {% else %} <li class="green">{{ book.btitle }}--{{ book.bpub_date }}</li> {% endif %} {% endfor %} </ul> </body> </html>
(3)、编写views.py
# 自定义过滤器视图 def temp_filters(request): """自定义过滤器""" books = BookInfo.objects.all() context = {'books': books} return my_render(request, 'booktest/temp_filters.html', context)
(4)、编写urls.py
# 配置自定义过滤器视图的url url(r'^temp_filters/$', views.temp_filters),
5、注释
(1)、单行注释语法
{# 注释内容 #}
(2)、多行注释语法
{% comment %} 注释内容 {% endcomment %}
三、模板继承
1、父模板
如果发现在多个模板中某些内容相同,那就应该把这段内容定义到父模板中。标签block:用于在父模板中预留区域,留给子模板填充差异性的内容,名字不能相同。 为了更好的可读性,建议给endblock标签写上名字,这个名字与对应的block名字相同。父模板中也可以使用上下文中传递过来的数据。
{%block 名称%} 预留区域,可以编写默认内容,也可以没有默认内容 {%endblock 名称%}
2、子模板
子模板中使用标签extends用来继承父模板,写在子模板文件的第一行。
{% extends "父模板路径"%}
子模版不用填充父模版中的所有预留区域,如果子模版没有填充,则使用父模版定义的默认值。
{%block 名称%} 实际填充内容 {{block.super}}用于获取父模板中block的内容 {%endblock 名称%}
3、示例
views.py
# 模板继承中子类视图 def child(request): """模板继承中子类视图""" return render(request, 'booktest/child.html', {}) # 模板继承中孙子类视图 def grandson(request): """模板继承中孙子类视图""" return render(request, 'booktest/grandson.html', {})
urls.py21
# 配置模板继承中子类的url url(r'^child/$', views.child), # 配置模板继承中孙子类的url url(r'^grandson/$', views.grandson),
父模版 base.html
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>{% block title %}父模板文件{% endblock title %}</title> </head> <body> <h1>导航条</h1> {% block b1 %} <h1>这是父模板b1块中的内容</h1> {% endblock b1 %} {% block b2 %} <h1>这是父模板b2块中的内容</h1> {% endblock b2 %} <h1>版权信息</h1> </body> </html>
子模板 child.html
{% extends 'booktest/base.html' %} {% block title %}子模板标题{% endblock title %} {% block b1 %} {# 获取父模板b1块中默认的内容 #} {{ block.super }} <h1>这是子模板重写后b1块中的内容</h1> {% block main_content %} {% endblock main_content %} {% endblock b1 %} {% block b2 %} {# 获取父模板b2块中默认的内容 #} {{ block.super }} <h1>这是子模板重写后b2块中的内容</h1> {% endblock b2 %}
孙子模版 grandson.html
{% extends 'booktest/child1.html' %} {% block b1 %} <h1>这是grandson b1块中的内容</h1> {% block main_content %} <h1>这是grandson main_content块中的内容</h1> {% endblock main_content %} {% endblock b1 %}
四、模版转义
1、什么是模版转义
模板对上下文传递的字符串进行输出时,会对以下字符自动转义。
小于号< 转换为 < 大于号> 转换为 > 单引号' 转换为 ' 双引号" 转换为 " 与符号& 转换为 &
2、转义示例
(1)、views.py
# 模板中的html标签转义 def escape(request): """模版中的html标签转义""" return render(request, 'booktest/escape.html', {'content': '<h1>字段中带有html标签的数据<h1/>'})
(2)、urls.py
# 配置模板中转义的url url(r'^escape/$', views.escape),
(3)、escape.html模版
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>html转义</title> </head> <body> <hr> <br> 使用不做任何处理的模版变量: {{ content }}<br> <br> <hr> <br> 使用safe过滤器进行转义处理: {{ content|safe}}<br> <br> <br> <hr> 使用autoescape关闭转义: {% autoescape off %} {{ content }} -- {{ content }} {{ content }} {% endautoescape %}<br> <br> <hr> <br> 模版变量的默认值不转义: {{ test_var|default:'<h1>test_var的默认值</h1>'}}<br> <br> <hr> <br> 手动进行转义: {{ test_var|default:'<h1>手动对test_vard的值进行转义<h1>'}} <br> <hr> <br> </body> </html>
五、反向解析
1、什么是反向解析
当某一个url配置的地址发生变化时,页面上使用反向解析生成地址的位置不需要发生变化。根据url 正则表达式的配置动态的生成url。
2、反向解析的使用方式
(1)、在项目同名的文件夹下的urls.py中配置namespace属性
(2)、在应用下的urls.py中配置name属性
(3)、在模板页面中通过namespace:name的方式定位对应的url
格式如下:
{% url 'namespace名字:name名字' %} 例如{% url 'booktest:fan2'%} 带位置参数: {% url 'namespace名字:name名字' 位置参数 %} 例如{% url 'booktest:fan2' 1%} 带关键字参数: {% url 'namespace名字:name名字' 关键字参数 %} 例如{% url 'booktest:fan2' id=1 %}
(4)、重定向中使用反向解析的用法(views.py中)
导入包: from django.core.urlresolvers import reverse 无参数的重定向: reverse('namespace名字:name名字') 如果有位置参数 reverse('namespace名字:name名字', args = 位置参数元组) 如果有关键字参数 reverse('namespace名字:name名字', kwargs=字典)
3、反向解析的示例
views.py
from django.shortcuts import render,redirect from django.core.urlresolvers import reverse # 导入反向解析函数的包 # url反向解析页面 def show_reverse(request): """url反向解析页面""" return render(request, 'booktest/reverse.html') # 带有位置参数的反向解析url:show_arg def show_arg(request, a, b): return HttpResponse(a+b) # 带有关键字参数的反向解析url:show_kwarg def show_kwarg(request, a, b): return HttpResponse(a+b) # 重定向中使用反向解析url def redirect_test(request): """重定向中的反向解析url""" # 重定向到不带参数的url r_url = reverse('booktest:index') # 重定向到带有位置参数的url r_url2 = reverse('booktest:show_arg', args=(1, 2)) print(r_url2) # 重定向到带有关键字参数的url r_url3 = reverse('booktest:show_kwarg', kwargs={'a': 1, 'b': 2}) print(r_url3) return redirect(r_url)
reverse.html
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>反向解析url</title> </head> <body> {% comment %} 反向解析url的时候,url后面为 应用名:url中的name属性的值。 如果有参数,就将参数直接写在后面 {% endcomment %} 使用反向解析生成的带有位置参数的url地址:<br> <a href="{% url 'booktest:show_arg' 1 2 %}">show_arg</a> <br> 使用反向解析生成带有关键字参数的url之地:<br> <a href="{% url 'booktest:show_kwarg' 3 4 %}">show_kwarg</a> </body> </html>
六、