做药的常用网站有哪些,营销软件商城,湖北城乡建设厅网站,怎么申请自己的企业邮箱视图层 1 视图函数
一个视图函数#xff0c;简称视图#xff0c;是一个简单的Python 函数#xff0c;它接受Web请求并且返回Web响应。响应可以是一张网页的HTML内容#xff0c;一个重定向#xff0c;一个404错误#xff0c;一个XML文档#xff0c;或者一张图片. . . 是…视图层 1 视图函数
一个视图函数简称视图是一个简单的Python 函数它接受Web请求并且返回Web响应。响应可以是一张网页的HTML内容一个重定向一个404错误一个XML文档或者一张图片. . . 是任何东西都可以。无论视图本身包含什么逻辑都要返回响应。代码写在哪里也无所谓只要它在你的Python目录下面。除此之外没有更多的要求了——可以说“没有什么神奇的地方”。为了将代码放在某处约定是将视图放置在项目或应用程序目录中的名为views.py的文件中。
下面是一个返回当前日期和时间作为HTML文档的视图
from django.shortcuts import render, HttpResponse, HttpResponseRedirect, redirect
import datetimedef current_datetime(request):now datetime.datetime.now()html htmlbodyIt is now %s./body/html % nowreturn HttpResponse(html)让我们逐行阅读上面的代码 首先我们从 django.shortcuts模块导入了HttpResponse类以及Python的datetime库。 接着我们定义了current_datetime函数。它就是视图函数。每个视图函数都使用HttpRequest对象作为第一个参数并且通常称之为request。 注意,视图函数的名称并不重要不需要用一个统一的命名方式来命名以便让Django识别它。我们将其命名为current_datetime是因为这个名称能够精确地反映出它的功能。 这个视图会返回一个HttpResponse对象其中包含生成的响应。每个视图函数都负责返回一个HttpResponse对象。 视图层熟练掌握两个对象即可请求对象(request)和响应对象(HttpResponse)
2 HttpRequest对象
request属性
django将请求报文中的请求行、首部信息、内容主体封装成 HttpRequest 类中的属性。 除了特殊说明的之外其他均为只读的
1.HttpRequest.GET一个类似于字典的对象包含 HTTP GET 的所有参数。详情请参考 QueryDict 对象。2.HttpRequest.POST一个类似于字典的对象如果请求中包含表单数据则将这些数据封装成 QueryDict 对象。POST 请求可以带有空的 POST 字典 —— 如果通过 HTTP POST 方法发送一个表单但是表单中没有任何的数据QueryDict 对象依然会被创建。因此不应该使用 if request.POST 来检查使用的是否是POST 方法应该使用 if request.method POST另外如果使用 POST 上传文件的话文件信息将包含在 FILES 属性中。注意键值对的值是多个的时候,比如checkbox类型的input标签select标签需要用request.POST.getlist(hobby)3.HttpRequest.body一个字符串代表请求报文的主体。在处理非 HTTP 形式的报文时非常有用例如二进制图片、XML,Json等。但是如果要处理表单数据的时候推荐还是使用 HttpRequest.POST 。4.HttpRequest.path一个字符串表示请求的路径组件不含域名。例如/music/bands/the_beatles/5.HttpRequest.method一个字符串表示请求使用的HTTP 方法。必须使用大写。例如GET、POST6.HttpRequest.encoding一个字符串表示提交的数据的编码方式如果为 None 则表示使用 DEFAULT_CHARSET 的设置默认为 utf-8。这个属性是可写的你可以修改它来修改访问表单数据使用的编码。接下来对属性的任何访问例如从 GET 或 POST 中读取数据将使用新的 encoding 值。如果你知道表单数据的编码不是 DEFAULT_CHARSET 则使用它。7.HttpRequest.META一个标准的Python 字典包含所有的HTTP 首部。具体的头部信息取决于客户端和服务器下面是一些示例取值CONTENT_LENGTH —— 请求的正文的长度是一个字符串。CONTENT_TYPE —— 请求的正文的MIME 类型。HTTP_ACCEPT —— 响应可接收的Content-Type。HTTP_ACCEPT_ENCODING —— 响应可接收的编码。HTTP_ACCEPT_LANGUAGE —— 响应可接收的语言。HTTP_HOST —— 客服端发送的HTTP Host 头部。HTTP_REFERER —— Referring 页面。HTTP_USER_AGENT —— 客户端的user-agent 字符串。QUERY_STRING —— 单个字符串形式的查询字符串未解析过的形式。REMOTE_ADDR —— 客户端的IP 地址。REMOTE_HOST —— 客户端的主机名。REMOTE_USER —— 服务器认证后的用户。REQUEST_METHOD —— 一个字符串例如GET 或POST。SERVER_NAME —— 服务器的主机名。SERVER_PORT —— 服务器的端口是一个字符串。从上面可以看到除 CONTENT_LENGTH 和 CONTENT_TYPE 之外请求中的任何 HTTP 首部转换为 META 的键时都会将所有字母大写并将连接符替换为下划线最后加上 HTTP_ 前缀。所以一个叫做 X-Bender 的头部将转换成 META 中的 HTTP_X_BENDER 键。8.HttpRequest.FILES一个类似于字典的对象包含所有的上传文件信息。FILES 中的每个键为input typefile name / 中的name值则为对应的数据。注意FILES 只有在请求的方法为POST 且提交的form 带有enctypemultipart/form-data 的情况下才会包含数据。否则FILES 将为一个空的类似于字典的对象。9.HttpRequest.COOKIES一个标准的Python 字典包含所有的cookie。键和值都为字符串。10.HttpRequest.session一个既可读又可写的类似于字典的对象表示当前的会话。只有当Django 启用会话的支持时才可用。完整的细节参见会话的文档。11.HttpRequest.user(用户认证组件下使用)一个 AUTH_USER_MODEL 类型的对象表示当前登录的用户。如果用户当前没有登录user 将设置为 django.contrib.auth.models.AnonymousUser 的一个实例。你可以通过 is_authenticated() 区分它们。例如if request.user.is_authenticated():# Do something for logged-in users.else:# Do something for anonymous users.user 只有当Django 启用 AuthenticationMiddleware 中间件时才可用。-------------------------------------------------------------------------------------匿名用户class models.AnonymousUserdjango.contrib.auth.models.AnonymousUser 类实现了django.contrib.auth.models.User 接口但具有下面几个不同点id 永远为None。username 永远为空字符串。get_username() 永远返回空字符串。is_staff 和 is_superuser 永远为False。is_active 永远为 False。groups 和 user_permissions 永远为空。is_anonymous() 返回True 而不是False。is_authenticated() 返回False 而不是True。set_password()、check_password()、save() 和delete() 引发 NotImplementedError。AnonymousUser.get_username() 以更好地模拟 django.contrib.auth.models.User。*/request常用方法 1.HttpRequest.get_full_path()返回 path如果可以将加上查询字符串。例如/music/bands/the_beatles/?printtrue注意和path的区别http://127.0.0.1:8001/order/?namelqzage102.HttpRequest.is_ajax()如果请求是通过XMLHttpRequest 发起的则返回True方法是检查 HTTP_X_REQUESTED_WITH 相应的首部是否是字符串XMLHttpRequest。大部分现代的 JavaScript 库都会发送这个头部。如果你编写自己的 XMLHttpRequest 调用在浏览器端你必须手工设置这个值来让 is_ajax() 可以工作。如果一个响应需要根据请求是否是通过AJAX 发起的并且你正在使用某种形式的缓存例如Django 的 cache middleware你应该使用 vary_on_headers(HTTP_X_REQUESTED_WITH) 装饰你的视图以让响应能够正确地缓存。3 HttpResponse对象
响应对象主要有三种形式
HttpResponse()render()redirect()
HttpResponse()括号内直接跟一个具体的字符串作为响应体比较直接很简单所以这里主要介绍后面两种形式。
render()
render(request, template_name[, context] 结合一个给定的模板和一个给定的上下文字典并返回一个渲染后的 HttpResponse 对象。
参数request 用于生成响应的请求对象。template_name要使用的模板的完整名称可选的参数context添加到模板上下文的一个字典。默认是一个空字典。如果字典中的某个值是可调用的视图将在渲染模板之前调用它。render方法就是将一个模板页面中的模板语法进行渲染最终渲染成一个html页面作为响应体。redirect()
传递要重定向的一个硬编码的URL
def my_view(request):...return redirect(/some/url/)也可以是一个完整的URL
def my_view(request):...return redirect(http://www.baidu.com/)
1301和302的区别。301和302状态码都表示重定向就是说浏览器在拿到服务器返回的这个状态码后会自动跳转到一个新的URL地址这个地址可以从响应的Location首部中获取用户看到的效果就是他输入的地址A瞬间变成了另一个地址B——这是它们的共同点。他们的不同在于。301表示旧地址A的资源已经被永久地移除了这个资源不可访问了搜索引擎在抓取新内容的同时也将旧的网址交换为重定向之后的网址302表示旧地址A的资源还在仍然可以访问这个重定向只是临时地从旧地址A跳转到地址B搜索引擎会抓取新的内容而保存旧的网址。 SEO302好于3012重定向原因
1网站调整如改变网页目录结构
2网页被移到一个新地址
3网页扩展名改变(如应用需要把.php改成.Html或.shtml)。这种情况下如果不做重定向则用户收藏夹或搜索引擎数据库中旧地址只能让访问客户得到一个404页面错误信息访问流量白白丧失再者某些注册了多个域名的网站也需要通过重定向让访问这些域名的用户自动跳转到主站点等。4 JsonResponse
向前端返回一个json格式字符串的两种方式
# 第一种方式
# import json
# data{name:lqz,age:18}
# data1[lqz,egon]
# return HttpResponse(json.dumps(data1))
# 第二种方式
from django.http import JsonResponse
# data {name: lqz, age: 18}
data1 [lqz, egon]
# return JsonResponse(data)
return JsonResponse(data1,safeFalse)5 CBV和FBV
CBV基于类的视图(Class base view)和FBV基于函数的视图Function base view
from django.views import View
class AddPublish(View):def dispatch(self, request, *args, **kwargs):print(request)print(args)print(kwargs)# 可以写类似装饰器的东西在前后加代码objsuper().dispatch(request, *args, **kwargs)return objdef get(self,request):return render(request,index.html)def post(self,request):requestreturn HttpResponse(post)6 简单文件上传
print(request.FILES)
print(type(request.FILES.get(file_name)))file_namerequest.FILES.get(file_name).name
from django.core.files.uploadedfile import InMemoryUploadedFile
with open(file_name,wb)as f:for i in request.FILES.get(file_name).chunks():f.write(i) 模板层
一 模版简介
你可能已经注意到我们在例子视图中返回文本的方式有点特别。 也就是说HTML被直接硬编码在 Python代码之中。
def current_datetime(request):now datetime.datetime.now()html htmlbodyIt is now %s./body/html % nowreturn HttpResponse(html)尽管这种技术便于解释视图是如何工作的但直接将HTML硬编码到你的视图里却并不是一个好主意。 让我们来看一下为什么
对页面设计进行的任何改变都必须对 Python 代码进行相应的修改。 站点设计的修改往往比底层 Python 代码的修改要频繁得多因此如果可以在不进行 Python 代码修改的情况下变更设计那将会方便得多。Python 代码编写和 HTML 设计是两项不同的工作大多数专业的网站开发环境都将他们分配给不同的人员甚至不同部门来完成。 设计者和HTML/CSS的编码人员不应该被要求去编辑Python的代码来完成他们的工作。程序员编写 Python代码和设计人员制作模板两项工作同时进行的效率是最高的远胜于让一个人等待另一个人完成对某个既包含 Python又包含 HTML 的文件的编辑工作。
基于这些原因将页面的设计和Python的代码分离开会更干净简洁更容易维护。 我们可以使用 Django的 *模板系统* (Template System)来实现这种模式这就是本章要具体讨论的问题
python的模板HTML代码模板语法
def current_time(req):# 原始的视图函数# import datetime# nowdatetime.datetime.now()# htmlhtmlbody现在时刻h1%s./h1/body/html %now# django模板修改的视图函数# from django.template import Template,Context# nowdatetime.datetime.now()# tTemplate(htmlbody现在时刻是:h1{{current_date}}/h1/body/html)# #tget_template(current_datetime.html)# cContext({current_date:str(now)})# htmlt.render(c)## return HttpResponse(html)#另一种写法(推荐)import datetimenowdatetime.datetime.now()return render(req, current_datetime.html, {current_date:str(now)[:19]})模版语法重点
变量{{ 变量名 }}1 深度查询 用句点符2 过滤器3 标签% % 二 模版语法之变量
在 Django 模板中遍历复杂数据结构的关键是句点字符, 语法变量名
views.py
def template_test(request):name lqzli [lqz, 1, 18]dic {name: lqz, age: 18}ll2 [{name: lqz, age: 18},{name: lqz2, age: 19},{name: egon, age: 20},{name: kevin, age: 23}]ll3[]class Person:def __init__(self, name):self.name namedef test(self):print(test函数)return 11classmethoddef test_classmethod(cls):print(类方法)return 类方法staticmethoddef static_method():print(静态方法)return 静态方法lqz Person(lqz)egon Person(egon)person_list [lqz, egon]bo Truete test()import datetimenowdatetime.datetime.now()link1a hrefhttps://www.baidu.com点我afrom django.utils import safestringlinksafestring.mark_safe(link1)# html特殊符号对照表http://tool.chinaz.com/Tools/htmlchar.aspx# 这样传到前台不会变成特殊字符因为django给处理了dotspades;# return render(request, template_index.html, {name:name,person_list:person_list})return render(request, template_index.html, locals())html
p{{ name }}/pp{{ li }}/pp{{ dic }}/pp{{ lqz }}/pp{{ person_list }}/pp{{ bo }}/pp{{ te }}/phrh3深度查询句点符/h3p{{ li.1 }}/pp{{ dic.name }}/pp{{ lqz.test }}/pp{{ lqz.name }}/pp{{ person_list.0 }}/pp{{ person_list.1.name }}/phrh3过滤器/h3{#注意冒号后面不能加空格#}p{{ now | date:Y-m-d H:i:s }}/p{#如果变量为空设置默认值,空数据None变量不存在都适用#}p{{ name |default:数据为空 }}/p{#计算长度只有一个参数#}p{{ person_list |length }}/p{#计算文件大小#}p{{ 1024 |filesizeformat }}/p{#字符串切片前闭后开前面取到后面取不到#}p{{ hello world lqz |slice:2:-1 }}/pp{{ hello world lqz |slice:2:5 }}/p{#截断字符至少三个起步因为会有三个省略号传负数123都是三个省略号#}p{{ world lqz |truncatechars:4 }}/p{#截断文字以空格做区分这个不算省略号#}p{{ 大帅比 谢谢 |truncatewords:1 }}/pp{{ link1 }}/pp{{ link1|safe }}/pp{{ link }}/ppspades;/pp{{ dot }}/p{#add 可以加负数传数字字符串都可以#}p{{ 10|add:-2 }}/pp{{ li.1|add:-2 }}/pp{{ li.1|add:2 }}/pp{{ li.1|add:2 }}/pp{{ li.1|add:-2e }}/p{#upper#}p{{ name|upper }}/pp{{ LQZ|lower }}/phrh3模版语法之标签/h3{#for 循环 循环列表循环字典循环列表对象#}ui{% for foo in dic %}{{ foo }}{% endfor %}{#也可以混用html标签#}{% for foo in li %}ulfoo/ul{% endfor %}/ui{#表格#}table border1{% for foo in ll2 %}trtd{{ foo.name }}/tdtd{{ foo.age }}/td/tr{% endfor %}/tabletable border1{#parentloop: {}, counter0: 0, counter: 1, revcounter: 4, revcounter0: 3, first: True, last: False}#}{% for foo in ll2 %}trtd{{ forloop.counter }}/tdtd{{ foo.name }}/tdtd{{ foo.age }}/td/tr{% endfor %}/table{% for foo in ll5 %}pfoo.name/p{% empty %}p空的/p{% endfor %}hrh3if判断/h3{% if name %}a hrefhi {{ name }}/aa href注销/a{% else %}a href请登录/aa href注册/a{% endif %}{#还有elif#}hrh3with/h3{% with ll2.0.name as n %}{{ n }}{% endwith %}{{ n }}{% load my_tag_filter %}{{ 3|multi_filter:3 }}{#传参必须用空格区分#}{% multi_tag 3 9 10 %}{#可以跟if连用#}{% if 3|multi_filter:3 9 %}p大于/p{% else %}p小于/p{% endif %}注意句点符也可以用来引用对象的方法(无参数方法):
h4字典:{{ dic.name.upper }}/h4三 模版之过滤器
语法
{{obj|filter__name:param}} 变量名字|过滤器名称变量default
如果一个变量是false或者为空使用给定的默认值。否则使用变量的值。例如
{{ value|default:nothing}}length
返回值的长度。它对字符串和列表都起作用。例如
{{ value|length }}如果 value 是 [‘a’, ‘b’, ‘c’, ‘d’]那么输出是 4。
filesizeformat
将值格式化为一个 “人类可读的” 文件尺寸 例如 13 KB, 4.1 MB, 102 bytes, 等等。例如
{{ value|filesizeformat }}如果 value 是 123456789输出将会是 117.7 MB。
date
如果 valuedatetime.datetime.now()
{{ value|date:Y-m-d}}slice
如果 value”hello world”
{{ value|slice:2:-1}}truncatechars
如果字符串字符多于指定的字符数量那么会被截断。截断的字符串将以可翻译的省略号序列“…”结尾。
参数要截断的字符数
例如
{{ value|truncatechars:9}}safe
Django的模板中会对HTML标签和JS等语法标签进行自动转义原因显而易见这样是为了安全。但是有的时候我们可能不希望这些HTML元素被转义比如我们做一个内容管理系统后台添加的文章中是经过修饰的这些修饰可能是通过一个类似于FCKeditor编辑加注了HTML修饰符的文本如果自动转义的话显示的就是保护HTML标签的源文件。为了在Django中关闭HTML的自动转义有两种方式如果是一个单独的变量我们可以通过过滤器“|safe”的方式告诉Django这段代码是安全的不必转义。比如
valuea href点击/a
{{ value|safe}}其它过滤器了解
过滤器描述示例upper以大写方式输出add给value加上一个数值addslashes单引号加上转义号capfirst第一个字母大写center输出指定长度的字符串把变量居中cut删除指定字符串date格式化日期default如果值不存在则使用默认值代替default_if_none如果值为None, 则使用默认值代替dictsort按某字段排序变量必须是一个dictionarydictsortreversed按某字段倒序排序变量必须是dictionarydivisibleby判断是否可以被数字整除escape按HTML转义比如将””转换为”lt”filesizeformat增加数字的可读性转换结果为13KB,89MB,3Bytes等first返回列表的第1个元素变量必须是一个列表floatformat转换为指定精度的小数默认保留1位小数get_digit从个位数开始截取指定位置的数字join用指定分隔符连接列表length返回列表中元素的个数或字符串长度length_is检查列表字符串长度是否符合指定的值linebreaks用或 标签包裹变量linebreaksbr用 标签代替换行符linenumbers为变量中的每一行加上行号ljust输出指定长度的字符串变量左对齐lower字符串变小写make_list将字符串转换为列表pluralize根据数字确定是否输出英文复数符号random返回列表的随机一项removetags删除字符串中指定的HTML标记rjust输出指定长度的字符串变量右对齐slice切片操作 返回列表slugify在字符串中留下减号和下划线其它符号删除空格用减号替换stringformat字符串格式化语法同pythontime返回日期的时间部分timesince以“到现在为止过了多长时间”显示时间变量timeuntil以“从现在开始到时间变量”还有多长时间显示时间变量title每个单词首字母大写truncatewords将字符串转换为省略表达方式truncatewords_html同上但保留其中的HTML标签urlencode将字符串中的特殊字符转换为url兼容表达方式urlize将变量字符串中的url由纯文本变为链接wordcount返回变量字符串中的单词数yesno
四 模版之标签
标签看起来像是这样的 {% tag %}
标签比变量更加复杂一些在输出中创建文本一些通过循环或逻辑来控制流程一些加载其后的变量将使用到的额外信息到模版中。
一些标签需要开始和结束标签 例如{% tag %} ...标签 内容 ... {% endtag %}for标签
遍历每一个元素
{% for person in person_list %}p{{ person.name }}/p
{% endfor %}#可以利用{% for obj in list reversed %}反向完成循环。遍历一个字典
{% for key,val in dic.items %}p{{ key }}:{{ val }}/p
{% endfor %}注循环序号可以通过forloop显示
forloop.counter The current iteration of the loop (1-indexed) 当前循环的索引值从1开始
forloop.counter0 The current iteration of the loop (0-indexed) 当前循环的索引值从0开始
forloop.revcounter The number of iterations from the end of the loop (1-indexed) 当前循环的倒序索引值从1开始
forloop.revcounter0 The number of iterations from the end of the loop (0-indexed) 当前循环的倒序索引值从0开始
forloop.first True if this is the first time through the loop 当前循环是不是第一次循环布尔值
forloop.last True if this is the last time through the loop 当前循环是不是最后一次循环布尔值
forloop.parentloop 本层循环的外层循环for … empty
# for 标签带有一个可选的{% empty %} 从句以便在给出的组是空的或者没有被找到时可以有所操作。
{% for person in person_list %}p{{ person.name }}/p{% empty %}psorry,no person here/p
{% endfor %}if 标签
# {% if %}会对一个变量求值如果它的值是True存在、不为空、且不是boolean类型的false值对应的内容块会输出。{% if num 100 or num 0 %}p无效/p
{% elif num 80 and num 100 %}p优秀/p
{% else %}p凑活吧/p
{% endif %}if语句支持 and 、or、、、、!、、、in、not in、is、is not判断。with
使用一个简单地名字缓存一个复杂的变量当你需要使用一个“昂贵的”方法比如访问数据库很多次的时候是非常有用的
例如
{% with totalbusiness.employees.count %}{{ total }} employee{{ total|pluralize }}
{% endwith %}
不要写成ascsrf_token
{% csrf_token%}这个标签用于跨站请求伪造保护
五 自定义标签和过滤器
1、在settings中的INSTALLED_APPS配置当前app不然django无法找到自定义的simple_tag.
2、在app中创建templatetags模块(模块名只能是templatetags
3、创建任意 .py 文件如my_tags.py
from django import template
from django.utils.safestring import mark_saferegister template.Library() #register的名字是固定的,不可改变register.filter
def filter_multi(v1,v2):return v1 * v2register.simple_tag
def simple_tag_multi(v1,v2):return v1 * v2register.simple_tag
def my_input(id,arg):result input typetext id%s class%s / %(id,arg,)return mark_safe(result)4、在使用自定义simple_tag和filter的html文件中导入之前创建的 my_tags.py
{%load my_tags %}5、使用simple_tag和filter如何调用
{% load xxx %} # num12
{{ num|filter_multi:2 }} #24{{ num|filter_multi:[22,333,4444] }}{% simple_tag_multi 2 5 %} 参数不限,但不能放在if for语句中
{% simple_tag_multi num 5 %}注意filter可以用在if等语句后simple_tag不可以
{% if num|filter_multi:30 100 %}{{ num|filter_multi:30 }}
{% endif %}六 模版导入入和继承
模版导入 语法{% include 模版名称 %}如{% include adv.html %}
div classadvdiv classpanel panel-defaultdiv classpanel-headingh3 classpanel-titlePanel title/h3/divdiv classpanel-bodyPanel content/div/divdiv classpanel panel-dangerdiv classpanel-headingh3 classpanel-titlePanel title/h3/divdiv classpanel-bodyPanel content/div/divdiv classpanel panel-warningdiv classpanel-headingh3 classpanel-titlePanel title/h3/divdiv classpanel-bodyPanel content/div/div
/div
!DOCTYPE html
html langen
headmeta charsetUTF-8titleTitle/titlelink relstylesheet href/static/bootstrap-3.3.7-dist/css/bootstrap.min.css{# link relstylesheet hrefhttps://cdn.bootcss.com/bootstrap/3.3.7/css/bootstrap.min.css integritysha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4VaPmSTsz/K68vbdEjh4u crossoriginanonymous#}style* {margin: 0;padding: 0;}.header {height: 50px;width: 100%;background-color: #369;}/style
/head
body
div classheader/divdiv classcontainerdiv classrowdiv classcol-md-3{% include adv.html %}/divdiv classcol-md-9{% block conn %}h1你好/h1{% endblock %}/div/div/div/body
/html
{% extends base.html %}{% block conn %}{{ block.super }}
是啊{% endblock conn%}模版继承
Django模版引擎中最强大也是最复杂的部分就是模版继承了。模版继承可以让您创建一个基本的“骨架”模版它包含您站点中的全部元素并且可以定义能够被子模版覆盖的 blocks 。
通过从下面这个例子开始可以容易的理解模版继承
!DOCTYPE html
html langen
headlink relstylesheet hrefstyle.css/title{% block title %}My amazing site{% endblock %}/title
/headbody
div idsidebar{% block sidebar %}ullia href/Home/a/lilia href/blog/Blog/a/li/ul{% endblock %}
/divdiv idcontent{% block content %}{% endblock %}
/div
/body
/html这个模版我们把它叫作 base.html 它定义了一个可以用于两列排版页面的简单HTML骨架。“子模版”的工作是用它们的内容填充空的blocks。
在这个例子中 block 标签定义了三个可以被子模版内容填充的block。 block 告诉模版引擎 子模版可能会覆盖掉模版中的这些位置。
子模版可能看起来是这样的
{% extends base.html %}{% block title %}My amazing blog{% endblock %}{% block content %}
{% for entry in blog_entries %}h2{{ entry.title }}/h2p{{ entry.body }}/p
{% endfor %}
{% endblock %}extends 标签是这里的关键。它告诉模版引擎这个模版“继承”了另一个模版。当模版系统处理这个模版时首先它将定位父模版——在此例中就是“base.html”。
那时模版引擎将注意到 base.html 中的三个 block 标签并用子模版中的内容来替换这些block。根据 blog_entries 的值输出可能看起来是这样的
!DOCTYPE html
html langen
headlink relstylesheet hrefstyle.css /titleMy amazing blog/title
/headbodydiv idsidebarullia href/Home/a/lilia href/blog/Blog/a/li/ul/divdiv idcontenth2Entry one/h2pThis is my first entry./ph2Entry two/h2pThis is my second entry./p/div
/body
/html
请注意子模版并没有定义 sidebar block所以系统使用了父模版中的值。父模版的 {% block %} 标签中的内容总是被用作备选内容fallback。这种方式使代码得到最大程度的复用并且使得添加内容到共享的内容区域更加简单例如部分范围内的导航。**这里是使用继承的一些提示**- 如果你在模版中使用 {% extends %} 标签它必须是模版中的第一个标签。其他的任何情况下模版继承都将无法工作。- 在base模版中设置越多的 {% block %} 标签越好。请记住子模版不必定义全部父模版中的blocks所以你可以在大多数blocks中填充合理的默认内容然后只定义你需要的那一个。多一点钩子总比少一点好。- 如果你发现你自己在大量的模版中复制内容那可能意味着你应该把内容移动到父模版中的一个 {% block %} 中。- If you need to get the content of the block from the parent template, the {{ block.super }} variable will do the trick. This is useful if you want to add to the contents of a parent block instead of completely overriding it. Data inserted using {{ block.super }} will not be automatically escaped (see the next section), since it was already escaped, if necessary, in the parent template.- 为了更好的可读性你也可以给你的 {% endblock %} 标签一个 *名字* 。例如{%block content %}...{%endblock content %}在大型模版中这个方法帮你清楚的看到哪一个 {% block %} 标签被关闭了。- 不能在一个模版中定义多个相同名字的 block 标签。七 静态文件相关
{% load static %}
img src{% static images/hi.jpg %} altHi! /引用JS文件时使用
{% load static %}
script src{% static mytest.js %}/script某个文件多处被用到可以存为一个变量
{% load static %}
{% static images/hi.jpg as myphoto %}
img src{{ myphoto }}/img使用get_static_prefix
{% load static %}
img src{% get_static_prefix %}images/hi.jpg altHi! /或者
{% load static %}
{% get_static_prefix as STATIC_PREFIX %}img src{{ STATIC_PREFIX }}images/hi.jpg altHi! /
img src{{ STATIC_PREFIX }}images/hi2.jpg altHello! /inclusion_tag
多用于返回html代码片段
示例
templatetags/my_inclusion.py
from django import template
register template.Library()register.inclusion_tag(result.html)
def show_results(n):n 1 if n 1 else int(n)data [第{}项.format(i) for i in range(1, n1)]return {data: data}templates/snippets/result.html
ul{% for choice in data %}li{{ choice }}/li{% endfor %}
/ultemplates/index.html
!DOCTYPE html
html langen
headmeta charsetUTF-8meta http-equivx-ua-compatible contentIEedgemeta nameviewport contentwidthdevice-width, initial-scale1titleinclusion_tag test/title
/head
body{% load inclusion_tag_test %}{% show_results 10 %}
/body
/html