模板标签使用示例
函数
def temp_tags(request):
“”“模板标签”“”
books = models.BookInfo.objects.all()
return render(request, ‘booktest/temp_tags.html’, {‘books’: books})
html代码
模板标签
{% for book in books %}
{% if book.id <= 2 %}
- {{ forloop.counter }}--{{ book.btitle }}
{% elif book.id <= 3 %}
- {{ forloop.counter }}--{{ book.btitle }}
{% else %}
- {{ forloop.counter }}--{{ book.btitle }}
{% endif %}
{% endfor %}
booktest/temp_tags.html
过滤器
过滤器其实就是python函数。
过滤器用于对模板变量进行操作。
-
date:改变日期的显示格式。
-
length:求长度。字符串,列表.
-
default:设置模板变量的默认值。
格式:
模板变量|过滤器:参数
自定义过滤器。
自定义的过滤器函数,至少有一个参数,最多两个
过滤器的使用示例
过滤器函数
def temp_filter(request):
“”“模板过滤器”“”
books = models.BookInfo.objects.all()
return render(request, ‘booktest/temp_filter.html’, {‘books’: books})
过滤器html代码
模板过滤器 模板标签
{% for book in books %}
{% if book.id <= 2 %}
-
- {{ book.btitle }}--{{ book.bpub_date|date:'Y-m-d' }}
{% else %}
{# 加了length后,会将原来的图书名编程图书名长度的数字 #}
- {{ book.btitle|length }}--{{ book.bpub_date }}
{% endif %}
{% endfor %}
default过滤器:
{# 如果content没有值,则过滤器会显示默认的值 #}
{{ content|default:“hello” }}
booktest/temp_filter.html
注意:过滤器中,冒号后不能加空格,
例如{{ book.bpub_date|date:‘Y-m-d’ }}是正确的,而{{ book.bpub_date|date: ‘Y-m-d’ }}是错误的。
否则会报错,Could not parse the remainder: ‘: ‘Y-m-d’’ from ‘book.bpub_date|date: ‘Y-m-d’’
自定义过滤器
自定义过滤器
-
1.在自己的应用下面新建一个 templatetags 文件夹,名字固定;
-
2.在templatetags文件夹下面新建一个py文件,名字自定义,比如filters.py;
-
3.1.在文件中,引入Library类;
-
3.2.创建一个Library类的对象;
-
3.3.定义自己的函数,给函数添加装饰器@register.filter进行过滤器装饰;
使用自定义装饰器
-
1.在需要使用的html文件中导入自定义装饰器文件,{% load filters %},即 load 文件名;
-
2.使用过滤器;
自定义过滤器示例
import django.template
创建一个Library类的对象
register = django.template.Library()
@register.filter
def mod(num):
“”“判断num是否为偶数”“”
如果传过来的num是偶数,则返回True,否则返回False
return num % 2 == 0
在html代码中使用模板过滤器
{% load filters %}
模板过滤器 模板标签
{% for book in books %}
{% if book.id|mod %}
-
- {{ book.id }}--{{ book.btitle }}--{{ book.bpub_date|date:'Y-m-d' }}
{% else %}
- {{ book.btitle }}--{{ book.bpub_date }}
{% endif %}
{% endfor %}
html使用一个参数的过滤器
两个参数的自定义过滤器
自定义过滤器
自定义的过滤器,最少有一个参数,最多有两个参数
只有一个参数的话,由|前面的参数传过来,两个参数的话,:后面再跟一个参数
应注意过滤器参数的前后顺序
@register.filter
def mod_val(num, val):
“”“判断num是否能把value整除”“”
return num % val == 0
html代码
{% load filters %}
模板过滤器 模板标签
{% for book in books %}
{# {% if book.id <= 2 %} #}
{# % if book.id|mod %} #}
{% if book.id|mod_val:3 %}
- {{ book.id }}--{{ book.btitle }}--{{ book.bpub_date|date:'Y-m-d' }}
{% else %}
{# 加了length后,会将原来的图书名编程图书名长度的数字 #}
- {{ book.btitle|length }}--{{ book.bpub_date }}
{% endif %}
{% endfor %}
default过滤器:
{# 如果content没有值,则过滤器会显示默认的值 #}
{{ content|default:“hello” }}
html使用两个参数的自定义过滤器
模板继承
模板继承也是为了重用html页面内容。
在父模板里可以定义块,使用标签:
{% block 块名 %}
块中间可以写内容,也可以不写
{% endblock 块名%}
子模板去继承父模板之后,可以重写父模板中的某一块的内容。
继承格式:
{% extends 父模板文件路径%}
{% block 块名 %}
{{ block.super}} #获取父模板中块的默认内容
重写的内容
{% endblock 块名%}
模板继承示例
base/母模板
{% block title %}base模板文件的title{% endblock title %} base模板的header
{% block b1 %}
base模板的block1
{% endblock b1 %}
{% block b2 %}
base模板的block1
{% endblock b2 %}
base模板的footer
child/子模板
{% extends ‘booktest/base.html’ %}
{% block title %}child模板中的title{% endblock title %}
{% block b1 %}
{{ block.super }}
child模板的block1
{% endblock b1 %}
{% block b2 %}
child模板的block2
{% endblock b2 %}
配套函数
def temp_inherit(request):
“”“返回child模板继承于base的文件”“”
return render(request, ‘booktest/child.html’)
在块里面还可以写块,需要注意endblock后面跟 块名 用以区分哪个块结束。
html转义
场景:编辑商品详情信息,数据表中保存的是html内容。
在模板上下文中的html标记默认是会被转义的。
小于号< 转换为<
大于号> 转换为>
单引号’ 转换为’
双引号" 转换为 "
与符号& 转换为 &
要关闭模板上下文字符串的转义:可以使用
{{ 模板变量|safe}}
也可以使用:
{% autoescape off %}
模板语言代码
{% endautoescape %}
模板硬编码中的字符串默认不会经过转义,如果需要转义,那需要手动进行转义。
safe和autoescape的区别在于,safe只能转义一个模板变量,而autoescape可以转义多个变量;
html转义示例
html_escape.html
模板转义 html转义结果:
{{ content }}
使用safe过滤器关闭转义结果:
{{ content|safe }}
使用autoescape关闭转义结果:
{% autoescape off %}
{{ content }}
{{ content }}
{% endautoescape %}
模板硬编码中的字符串默认不会转义,即会经过html渲染:
{{ test|default:‘
hello
’ }}
手动对硬编码进行转义:
{{ test|default:‘<h1>hello</h1>’ }}
配套函数
/html_escape
def html_escape(request):
“”“模板转义”“”
return render(request, ‘booktest/html_escape.html’, {‘content’: ‘
hello
’})验证码
在用户注册、登录页面,为了防止暴力请求,可以加入验证码功能,
如果验证码错误,则不需要继续处理,可以减轻业务服务器、数据库服务器的压力。
自实现验证码
安装pillow
pip install Pillow==3.4.1
编写函数/视图
from PIL import Image, ImageDraw, ImageFont
from django.utils.six import BytesIO
def verify_code(request):
引入随机函数模块
import random
定义变量,用于画面的背景色、宽、高
bgcolor = (random.randrange(20, 100), random.randrange(
20, 100), 255)
width = 100
height = 25
创建画面对象
im = Image.new(‘RGB’, (width, height), bgcolor)
创建画笔对象
draw = ImageDraw.Draw(im)
调用画笔的point()函数绘制噪点
for i in range(0, 100):
xy = (random.randrange(0, width), random.randrange(0, height))
fill = (random.randrange(0, 255), 255, random.randrange(0, 255))
draw.point(xy, fill=fill)
定义验证码的备选值
str1 = ‘ABCD123EFGHIJK456LMNOPQRS789TUVWXYZ0’
随机选取4个值作为验证码
rand_str = ‘’
for i in range(0, 4):
rand_str += str1[random.randrange(0, len(str1))]
构造字体对象,ubuntu的字体路径为“/usr/share/fonts/truetype/freefont”
font = ImageFont.truetype(‘FreeMono.ttf’, 23)
构造字体颜色
fontcolor = (255, random.randrange(0, 255), random.randrange(0, 255))
绘制4个字
draw.text((5, 2), rand_str[0], font=font, fill=fontcolor)
draw.text((25, 2), rand_str[1], font=font, fill=fontcolor)
draw.text((50, 2), rand_str[2], font=font, fill=fontcolor)
draw.text((75, 2), rand_str[3], font=font, fill=fontcolor)
释放画笔
del draw
存入session,用于做进一步验证
request.session[‘verifycode’] = rand_str
内存文件操作
buf = BytesIO()
将图片保存在内存中,文件类型为png
im.save(buf, ‘png’)
将内存中的图片数据返回给客户端,MIME类型为图片png
return HttpResponse(buf.getvalue(), ‘image/png’)
自实现验证码函数
查看验证码
url(r’^verify_code/$', views.verify_code),
在网页中使用验证码
Login {% csrf_token %}
用户:
密码:
记住用户名
html中使用验证码
登录校验验证码函数
def login_check(request):
1.获取用户名和密码
username = request.POST.get(“username”)
password = request.POST.get(“password”)
remember = request.POST.get(“remember”)
print(username, password)
获取用户输入的验证码
vcode1 = request.POST.get(‘vcode’)
获取session中保存的验证码
vcode2 = request.session.get(‘verifycode’)
进行验证码校验
if vcode1 != vcode2:
验证码错误
return redirect(‘/login’)
2.进行校验
3.返回应答
if username == “yifchan” and password == “yifchan”:
response = redirect(“/index”)
response = redirect(“/change_pwd”)
判断是否需要记住用户名
if remember == ‘on’:
设置cookie username-过期时间为1周
response.set_cookie(‘username’, username, max_age=7 * 24 * 3600)
记住用户登录状态
只有session中有islogin,就认为用户已经登录
request.session[‘islogin’] = True
request.session[‘username’] = username
return response
else:
return HttpResponse(“账号或密码错误”)
验证码校验函数
url反向解析
当某一个url配置的地址发生变化时,页面上使用反向解析生成地址的位置不需要发生变化。
根据url 正则表达式的配置动态的生成url。
在项目urls中包含具体应用的urls文件时指定namespace;
urlpatterns = [
url(r’^admin/', admin.site.urls),
url(r’^', include(‘booktest.urls’, namespace=‘booktest’)),
]
在应用的urls中配置是指定name;
urlpatterns = [
url(r’^index/$', views.index, name=‘index’),
url(r’^url_reverse/$', views.url_reverse), #
url(r’^show_args/(\d+)/(\d+)$', views.show_args, name=‘show_args’), # 捕获位置参数
url(r’^show_kwargs/(?P\d+)/(?P\d+)$', views.show_kwargs, name=‘show_kwargs’), # 捕获关键字参数
]
在模板文件中使用时,格式如下:
{% url ‘namespace名字:name’ %} 例如{% url ‘booktest:fan2’ %}
带位置参数:
{% url ‘namespace名字:name’ 参数 %} 例如{% url ‘booktest:fan2’ 1 %}
带关键字参数:
{% url ‘namespace名字:name’ 关键字参数 %} 例如{% url ‘booktest:fan2’ id=1 %}
在视图中/重定向的时候使用反向解析:
from django.core.urlresolvers import reverse
无参数:
reverse(‘namespace名字:name名字’)
如果有位置参数
reverse(‘namespace名字:name名字’, args = 位置参数元组)
如果有关键字参数
reverse(‘namespace名字:name名字’, kwargs=字典)
url反向解析示例
项目下的url文件
urlpatterns = [
url(r’^admin/', admin.site.urls),
url(r’^', include(‘booktest.urls’, namespace=‘booktest’)),
]
应用下的url文件
urlpatterns = [
url(r’^index/$', views.index, name=‘index’),
url(r’^url_reverse/$', views.url_reverse), #
url(r’^show_args/(\d+)/(\d+)$', views.show_args, name=‘show_args’), # 捕获位置参数
url(r’^show_kwargs/(?P\d+)/(?P\d+)$', views.show_kwargs, name=‘show_kwargs’), # 捕获关键字参数
url(r’^test_reverse/$', views.test_reverse, name=‘test_reverse’), # 视图使用反向解析
]
模板中使用url反向解析
配套函数
def url_reverse(request):
return render(request, ‘booktest/url_reverse.html’)
def show_args(request, a, b):
return HttpResponse(a+‘:’+b)
def show_kwargs(request, c, d):
return HttpResponse(c+‘:’+d)
url_reverse.html
url反向解析 index链接:
url反向解析生成index链接:
位置参数 /show_args/1/2:
动态生成/show_args/1/2:
关键字参数 /show_kwargs/3/4:
动态生成/show_kwargs/3/4:
视图中使用反向解析
反向解析函数
如果你也是看准了Python,想自学Python,在这里为大家准备了丰厚的免费学习大礼包,带大家一起学习,给大家剖析Python兼职、就业行情前景的这些事儿。
一、Python所有方向的学习路线
Python所有方向路线就是把Python常用的技术点做整理,形成各个领域的知识点汇总,它的用处就在于,你可以按照上面的知识点去找对应的学习资源,保证自己学得较为全面。
二、学习软件
工欲善其必先利其器。学习Python常用的开发软件都在这里了,给大家节省了很多时间。
三、全套PDF电子书
书籍的好处就在于权威和体系健全,刚开始学习的时候你可以只看视频或者听某个人讲课,但等你学完之后,你觉得你掌握了,这时候建议还是得去看一下书籍,看权威技术书籍也是每个程序员必经之路。
四、入门学习视频
我们在看视频学习的时候,不能光动眼动脑不动手,比较科学的学习方法是在理解之后运用它们,这时候练手项目就很适合了。
四、实战案例
光学理论是没用的,要学会跟着一起敲,要动手实操,才能将自己的所学运用到实际当中去,这时候可以搞点实战案例来学习。
五、面试资料
我们学习Python必然是为了找到高薪的工作,下面这些面试题是来自阿里、腾讯、字节等一线互联网大厂最新的面试资料,并且有阿里大佬给出了权威的解答,刷完这一套面试资料相信大家都能找到满意的工作。
成为一个Python程序员专家或许需要花费数年时间,但是打下坚实的基础只要几周就可以,如果你按照我提供的学习路线以及资料有意识地去实践,你就有很大可能成功!
最后祝你好运!!!网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。
一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!