Template Introduction
- As a web framework, Django provides templates that make it easy to dynamically generate HTML
- The template system is dedicated to expressing appearances, not program logic
- Templates are designed to separate the business logic (view) from the display (template), one view can use either template, and a template can be used by multiple views
- Template contains
- Static part of HTML
- Dynamic Insert Content Section
- Django Template language, abbreviated DTL, defined in the Django.template package
- The settings.py generated by the Startproject command defines values about the template:
- Dirs defines a list of directories that the template engine searches in list order to find template source files
- App_dirs tell the template engine if it should look for templates in each installed app
- Common way: Create a templates directory at the root of the project, set the dirs value
DIRS=[os.path.join(BASE_DIR,"templates")]
Template processing
- The Django processing template is divided into two stages
- STEP1 load: Finds a template based on a given identity and then pre-process it, usually compiling it in memory.
loader.get_template(template_name),返回一个Template对象
- STEP2 rendering: Using context data to interpolate a template and return the resulting string
Template对象的render(RequestContext)方法,使用context渲染模板
from django.template import loader, RequestContextfrom django.http import HttpResponsedef index(request): tem = loader.get_template(‘temtest/index.html‘) context = RequestContext(request, {}) return HttpResponse(tem.render(context))
Shortcut functions
- To reduce the duplication of code that loads templates and render templates, Django provides shortcut functions
- Render_to_string ("")
- Render (Request, ' template ', context)
from django.shortcuts import renderdef index(request): return render(request, ‘temtest/index.html‘)
Defining templates
- The template language includes
- Variable
- Label {% code block%}
- Filter filters
- Comment {# code or HTML #}
Variable
{{ variable }}
- When the template engine encounters a variable, the variable is evaluated and the result is output
- The variable name must consist of a letter, a number, an underscore (which cannot begin with an underscore), and a dot
- When the template engine encounters a point ("."), it is queried in the following order:
- Dictionary queries, for example: foo["Bar"]
- property or method query, for example: Foo.bar
- Numeric index query, for example: Foo[bar]
- If the variable does not exist, the template system will insert "(empty string)
- Parameters cannot be passed when calling a method in a template
Methods for invoking objects in a template
- Define class Heroinfo in models.py
from django.db import modelsclass HeroInfo(models.Model): ... def showName(self): return self.hname
- Passing Heroinfo objects in views.py
from django.shortcuts import renderfrom models import *def index(request): hero = HeroInfo(hname=‘abc‘) context = {‘hero‘: hero} return render(request, ‘temtest/detail.html‘, context)
- Called in the template detail.html
{{hero.showName}}
Label
- Syntax: {% tag%}
- Role
- Creating text in the output
- Control loops or logic
- Load external information into the template for future variables to use
- For label
{ %for ... in ...%}循环逻辑{{forloop.counter}}表示当前是第几次循环{ %empty%}给出的列表为或列表不存在时,执行此处{ %endfor%}
{ %if ...%}逻辑1{ %elif ...%}逻辑2{ %else%}逻辑3{ %endif%}
{ % comment % }多行注释{ % endcomment % }
- Include: Load the template and render it with the parameters within the tag
{ %include "foo/bar.html" % }
{ % url ‘name‘ p1 p2 %}
- Csrf_token: This tag is used for cross-site request forgery protection
{ % csrf_token %}
- Boolean tags: and, or,and higher precedence than or
- block, extends: see "template Inheritance"
- Autoescape: See "HTML Escape"
Filter filters
- Syntax: {{variable | filter}}, for example {{Name|lower}}, indicates that the value of the variable name is changed to lowercase output
- Using pipe symbols (|) To apply the filter
- Change the calculation result of a variable by using a filter
- You can use the filter binding operator in the IF tag
if list1|length > 1
- Filters can be "concatenated" to form a filter chain
name|lower|upper
- Filters can pass parameters, and parameters are wrapped in quotation marks.
list|join:", "
- Default: If a variable is not provided, or if the value is False or empty, the value of the variable is used otherwise
value|default:"什么也没有"
- Date: Formats a date variable according to the given format
value|date:‘Y-m-d‘
- Escape: See "HTML Escape"
- Click to view detailed filters
Comments
{#...#}
- Comments can contain any template code, either valid or invalid.
{# { % if foo % }bar{ % else % } #}
- Use comment tags to annotate multiple lines of content in a template
Example
- Query all hero information displayed, ask for odd rows to appear in red, even lines to be shown in blue
Template inheritance
- Template inheritance reduces the duplication of page content and enables reuse of page content
- Typical application: The site's head, tail is the same, the content can be defined in the parent template, the child template does not need to repeat the definition
- Block tag: Reserve an area in a parent template, populate it in a child template
- Extends inheritance: Inherit, write in first line of template file
- Define Parent Template base.html
{ %block block_name%}这里可以定义默认值如果不定义默认值,则表示空字符串{ %endblock%}
- Define a child template index.html
{ % extends "base.html" %}
- Populating a reserved area with a block in a child template
{ %block block_name%}实际填充内容{ %endblock%}
Description
- If you use a extends tag in a template, it must be the first label in the template
- You cannot define multiple block tags of the same name in one template
- The child template does not have to define blocks in all parent templates, and if the sub-template does not have a block defined, the default values in the parent template are used
- If you find that you are copying a lot of content in a template, you should move the content to the parent template
- Use to get the contents of a block in the parent template
- For better readability, you can give a name to the Endblock tag.
{ % block block_name %}区域内容{ % endblock block_name %}
Three-tier inheritance structure
- Three-tier inheritance structure maximizes code reuse and makes adding content easier
- As a common e-commerce page
1. Create a root-level template
- Name is "base.html"
- Store shared content across the site
<!DOCTYPE html>
2. Create a branch template
- Inherit from base.html
- Named "Base_*. html"
- Define content that is common to specific branches
- Define Base_goods.html
{%extends ‘temtest/base.html‘%}{%block title%}商品{%endblock%}{%block left%}
{%extends ‘temtest/base.html‘%}{%block title%}用户中心{%endblock%}{%block left%}<font color=‘blue‘>user left</font>{%endblock%}
- Define index.html, inherit from base.html, do not need to write left block
{%extends ‘temtest/base.html‘%}{%block content%}首页内容{%endblock content%}
3. Create a template for a specific page, inheriting from the branch template
- Define Product List Page goodslist.html
{%extends ‘temtest/base_goods.html‘%}{%block content%}商品正文列表{%endblock content%}
- Define User Password page userpwd.html
{%extends ‘temtest/base_user.html‘%}{%block content%}用户密码修改{%endblock content%}
4. The view invokes the specific page and passes the data needed in the template
logo=‘welcome to itcast‘def index(request): return render(request, ‘temtest/index.html‘, {‘logo‘: logo})
- Product List View Goodslist
def goodslist(request): return render(request, ‘temtest/goodslist.html‘, {‘logo‘: logo})
- User Password View Userpwd
def userpwd(request): return render(request, ‘temtest/userpwd.html‘, {‘logo‘: logo})
5. Configure URLsfrom django.conf.urls import urlfrom . import viewsurlpatterns = [ url(r‘^$‘, views.index, name=‘index‘), url(r‘^list/$‘, views.goodslist, name=‘list‘), url(r‘^pwd/$‘, views.userpwd, name=‘pwd‘),]
HTML escape
- Django automatically HTML-escapes the string, such as the following values in the template:
视图代码:def index(request): return render(request, ‘temtest/index2.html‘, { ‘t1‘: ‘
Characters that will be automatically escaped
- HTML escape, which is the output of the included HTML tags, is not interpreted, because when the user submits the string, it may contain some offensive code, such as JS script
- Django automatically escapes the following characters:
< 会转换为<> 会转换为>‘ (单引号) 会转换为'" (双引号)会转换为 "& 会转换为 &
- Use escape filter When displaying untrusted variables, generally omitted because Django automatically escapes
{{t1|escape}}
Turn off escape
- Use safe filters for variables
{{ data|safe }}
- Use Autoescape tags for code blocks
{ % autoescape off %}{{ body }}{ % endautoescape %}
- Label Autoescape accept on or off parameters
- The auto-escape label is closed in the base template and is also closed in the child template
String literals
{ { data|default:"<b>123</b>" }}
{ { data|default:"<b>123</b>" }}
Csrf
- Full name Cross site request forgery, multi-site requests forgery
- Some malicious websites contain links, form buttons, or JavaScript that use authentication information from logged-in users in their browsers to try to do something on your site, which is a cross-site attack
- Demo CSRF as follows
- Create view csrf1 for presentation forms, Csrf2 for receiving post requests
def csrf1(request): return render(request,‘booktest/csrf1.html‘)def csrf2(request): uname=request.POST[‘uname‘] return render(request,‘booktest/csrf2.html‘,{‘uname‘:uname})
url(r‘^csrf1/$‘, views.csrf1),url(r‘^csrf2/$‘, views.csrf2),
- Create a template csrf1.html used to show the form
- Create a template Csrf2 to show the results received
- Access in the browser, see the effect, error is as follows:
- Annotation of the middleware code ' Django.middleware.csrf.CsrfViewMiddleware ' in settings.py
- View Csrf1 source code, copy, build an HTML file in your own website, paste the source, access to view the effect
Use of anti-CSRF
- The Django template provides a way to prevent cross-site attacks using the following steps:
- Step1: Enable ' Django.middleware.csrf.CsrfViewMiddleware ' middleware in settings.py, which is enabled by default when creating a project
- Step2: Adding tags to csrf1.html
<form>{% csrf_token %}...</form>
- Step3: Test the two requests just now, found that the cross-site request was rejected, the effect is as
Cancel Protection
- If some views do not require protection, you can use the adorner csrf_exempt, the template does not need to write the label, modify the Csrf2 view as follows
from django.views.decorators.csrf import csrf_exempt@csrf_exemptdef csrf2(request): uname=request.POST[‘uname‘] return render(request,‘booktest/csrf2.html‘,{‘uname‘:uname})
- Running the above two requests, the discovery can request
Protection principle
- After adding the tag, you can view the source code and find the following code
<input type=‘hidden‘ name=‘csrfmiddlewaretoken‘ value=‘nGjAB3Md9ZSb4NmG1sXDolPmh3bR2g59‘ />
- In the browser's debugging tool, you can view cookie information via the Network tab
- This site automatically adds cookie information, such as
- View cross-site information, and no cookie information, even if you add the hidden field code above, you can also find access to the
- Conclusion: Django's csrf is not completely secure.
- When a request is submitted, the middleware ' Django.middleware.csrf.CsrfViewMiddleware ' validates the submitted cookie and the contents of the hidden domain, and returns a 403 error if it fails
Verification Code
- In the user registration, login page, in order to prevent violent requests, you can add the verification code function, if the code is wrong, you do not need to continue processing, can alleviate some of the server pressure
- The use of verification code is also an effective way to prevent CRSF
- Verification code effects such as:
Verification Code View
From django.http import httpresponsedef verifycode (Request): #引入绘图模块 from PIL import Image, Imagedraw, Imagefont #引入随机函数模块 import random #定义变量 for background color, width and height bgcolor = (random.randrange (20, 100), Random.randrange ), 255) width = height = #创建画面对象 im = image.new (' RGB ', (width, height), bgcolor) #创建画笔对象 draw = I Magedraw.draw (IM) #调用画笔的point () function draws noise for I in range (0, +): XY = (random.randrange (0, width), Random.randra Nge (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))] #构造字体对象 font = imagefont.truetype (' Freemono.ttf ', 23°c) #构造字 Body color FontColor = (255, random.randrange (0, 255), Random.randrange (0, 255)) #绘制4个字 Draw.text ((5, 2), rand_str[0], F Ont=font, Fill=fontcolor) Draw.text ((2), rand_str[1], Font=font, Fill=fontcolor) Draw.text ((2), rand_str[2], Font=font, Fill=fontcol OR) Draw.text ((2), rand_str[3], Font=font, Fill=fontcolor) #释放画笔 del Draw #存入session for further verification Request.s ession[' verifycode ' = rand_str #内存文件操作 import Cstringio buf = Cstringio.stringio () #将图片保存在内存中, the file type is PNG im. Save (buf, ' png ') #将内存中的图片数据返回给客户端, MIME type is picture PNG return HttpResponse (Buf.getvalue (), ' image/png ')
Configure URLs
- To define the URL of the request Verification Code view in urls.py
from . import viewsUtilurlpatterns = [ url(r‘^verifycode/$‘, viewsUtil.verifycode),]
Show Verification Code
- Using the IMG tag in the template, src points to the captcha view
- Start the server to see the display success
- Extension: Click "Can't see, change a", you can change a new verification code
<script type="text/javascript" src="/static/jquery-1.12.4.min.js"></script><script type="text/javascript"> $(function(){ $(‘#verifycodeChange‘).css(‘cursor‘,‘pointer‘).click(function() { $(‘#verifycode‘).attr(‘src‘,$(‘#verifycode‘).attr(‘src‘)+1) }); });</script><span id=‘verifycodeChange‘>看不清,换一个</span>
- To be able to implement the submit function, you need to add the form and input tags
<form method=‘post‘ action=‘/verifycodeValid/‘> <input type="text" name="vc"> <span id=‘verifycodeChange‘>看不清,换一个</span><br><input type="submit" value="提交"></form>
Verify
- Receive the requested information, as compared to the content in the session
from django.http import HttpResponsedef verifycodeValid(request): vc = request.POST[‘vc‘] if vc.upper() == request.session[‘verifycode‘]: return HttpResponse(‘ok‘) else: return HttpResponse(‘no‘)
- Configure the URL for validation processing
urlpatterns = [ url(r‘^verifycodeValid/$‘, views.verifycodeValid),]
Third party
- Can search the "Verification Code" online, find some third-party verification code to provide the website, read the document, use to the project
Python django-4 templates