Django:(2)视图层&模板层
视图函数
一个视图函数,简称视图,是一个简单的Python 函数,它接受Web请求并且返回Web响应。响应可以是一张网页的HTML内容,一个重定向,一个404错误,一个XML文档,或者一张图片. . . 是任何东西都可以。无论视图本身包含什么逻辑,都要返回响应。代码写在哪里也无所谓,只要它在你的Python目录下面;为了将代码放在某处,约定是将视图放置在项目或应用程序目录中的名为views.py的文件中。
视图请求对象
request对象:包含所有的请求信息(浏览器给服务器发过来的是一堆字符串)
1. 属性:
1.1 请求方式:
request.method:获取请求方式(GET/POST) # 地址栏发过来的请求默认都是GET请求;<form mehtod="post">为POST请求
<form action="" method="post"></form>中的action如果为空,默认是往当前页面的url发送请求;如果只写了路径(如 /login/),默认是往当前页面的IP和端口拼接该路径发送请求 1.2 请求数据:
request.GET:获取所有的GET请求信息(字典形式)
request.POST:获取所有的POST请求信息(字典形式) 1.3 http://127.0.0.1:8000/index/?name=1&age=2 GET请求数据中某个值的获取:
request.GET.get("name")
request.GET.get("age")
request.POST.get("xxx") 同理 1.4 request.path:获取请求路径(如:/login/)
"""
url组成:
协议(http):IP:port/路径?get请求数据
如:http://127.0.0.1:8000/index/?name=1&age=2 """
# 127.0.0.1:8000 也有访问路径,根目录、根路径(/)
# 在url控制器中添加根路径: re_path(r"^$",views.index)
# url控制器中 路径和函数是一对一或多对一的关系 2. 方法:
2.1 request.get_full_path():获取路径和后面的get请求数据
视图响应对象
响应对象主要有三种形式:
HttpResponse()
render()
redirect()
HttpResponse()括号内直接跟一个具体的字符串作为响应体。(html标签也能渲染出来)
render用法:render(request,template_name[, context]) 如:render(request,"index.html",{"timer":ctime})
render()方法:结合一个给定的模板和一个给定的上下文字典,并返回一个渲染后的 HttpResponse 对象。
参数:
- request: 用于生成响应的请求对象。
- template_name:模板文件;要使用的模板的完整名称
- context:可选参数;添加到模板上下文的一个字典。默认是一个空字典。如果第二个参数中的html文件中有模板语法({{}})且字典中的某个值是可调用的,视图将在渲染模板之前调用它。
render方法就是将一个模板页面中的模板语法({{}})进行渲染,最终渲染成一个html页面作为响应体。
注:不含正则时也可使用 path;有正则需要用re_path
redirect()用法:
1.传递要重定向的一个硬编码的URL:
def my_view(request):
...
return redirect('/some/url/')
2. 也可以是一个完整的URL:
def my_view(request):
...
return redirect('http://example.com/')
模板层
templates文件夹下面的文件都叫模板文件;只不过有的包含模板语法(这种情况下,在把html页面发送给客户端之前,会先有一个解析模板语法的过程),有的不包含
模板语法之变量:
project的urls.py
from django.contrib import admin
from django.urls import path from app01 import views
urlpatterns = [
path('admin/', admin.site.urls),
path(r"index/",views.index)
]
app01/views.py
from django.shortcuts import render # Create your views here. def index(request):
"""
模板语法只有两个:
(1)、{{}} : 用于渲染变量
1. 深度查询:句点符
2. 过虑器
(2)、 {% %} : 用于渲染标签
:param request:
:return:
""" name = "neo"
i = 10
l = [1,2,"a"]
info = {"name":"neo","age":22}
b = True class Person(object):
def __init__(self,name,age):
self.name = name
self.age = age
alex = Person("alex",33)
egon = Person("egon",22)
person_list = [alex,egon] # return render(request,"index.html",{"name":name})
# 如果变量特别多,可利用 locals():作用就是把所有的局部变量按照字典的形式传到 render()的第三个形参位置;传的方式是按照 {"name":name,"i":i,...}这种方式
return render(request,"index.html",locals())
templates/index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<p>{{ name }}</p>
<p>{{ i }}</p>
<p>{{ l }}</p>
<p>{{ b }}</p>
<p>{{ alex }}</p>
<p>{{ person_list }}</p>
<p>{{ info }}</p>
<hr> 深度查询:利用点来完成
{# 想要列表l的第二个元素: l.1 #}
<p>{{ l.1 }}</p> {# 获取字典info中name那个key对应的value #}
<p>{{ info.name }}</p> {# 获取对象alex的name属性值 #}
<p>{{ alex.name }}</p> {# 获取person_list列表中第2个对象的age属性值 #}
<p>{{ person_list.1.age }}</p> </body>
</html>
模板之过虑器:
project的urls.py
from django.contrib import admin
from django.urls import path from app01 import views
urlpatterns = [
path('admin/', admin.site.urls),
path(r"index/",views.index),
path(r"login/",views.login)
]
app01/views.py
from django.shortcuts import render,HttpResponse # Create your views here. def index(request):
"""
模板语法只有两个:
(1)、{{}} : 用于渲染变量
1. 深度查询:句点符
2. 过虑器: {{val | filter_name: 参数}}
(2)、 {% %} : 用于渲染标签
:param request:
:return:
""" # 深度查询:句点符
name = "neo"
i = 10
l = [1,2,"a"]
info = {"name":"neo","age":22}
b = True class Person(object):
def __init__(self,name,age):
self.name = name
self.age = age
alex = Person("alex",33)
egon = Person("egon",22)
person_list = [alex,egon] # 过虑器
import datetime
now = datetime.datetime.now() empty_list = []
file_size = 1235467
str = "hello world"
text = "Django is a high-level Python Web framework that encourages rapid development and clean, pragmatic design. Built by experienced developers, it takes care of much of the hassle of Web development, so you can focus on writing your app without needing to reinvent the wheel. It’s free and open source."
link = "<a href='#'>click</a>" # 模板之标签
num = 90 # return render(request,"index.html",{"name":name})
# 如果变量特别多,可利用 locals():作用就是把所有的局部变量按照字典的形式传到 render()的第三个形参位置;传的方式是按照 {"name":name,"i":i,...}这种方式
return render(request,"index.html",locals()) def login(request):
if request.method == "POST":
return HttpResponse("OK")
return render(request,"login.html") # login.html中含有模板语法,因为有{% csrf_token %};所以发送给客户端之前会先渲染模板语法
templates/index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<p>{{ name }}</p>
<p>{{ i }}</p>
<p>{{ l }}</p>
<p>{{ b }}</p>
<p>{{ alex }}</p>
<p>{{ person_list }}</p>
<p>{{ info }}</p>
<hr> {#深度查询:利用点来完成#}
{# 想要列表l的第二个元素: l.1 #}
<p>{{ l.1 }}</p> {# 获取字典info中name那个key对应的value #}
<p>{{ info.name }}</p> {# 获取对象alex的name属性值 #}
<p>{{ alex.name }}</p> {# 获取person_list列表中第2个对象的age属性值 #}
<p>{{ person_list.1.age }}</p>
<hr> <h3>过虑器</h3>
{# 时间类型会自动给你渲染好格式,如:June 6, 2018, 4:32 p.m. #}
{{ now }}
{# 把上述时间类型通过过虑器转化格式;date是Django提供的过虑器名字,固定的 #}
{{ now|date:"Y-m-d" }} {#过虑器#}
{# default :如果一个变量是false或者为空,使用给定的默认值。否则,使用变量的值。#}
{{ empty_list|default:"数据为空" }}
{#length:返回值的长度。它对字符串和列表都起作用。#}
{{ person_list|length }}
{#filesizeformat:将值格式化为一个 “人类可读的” 文件尺寸 (例如 '13 KB', '4.1 MB', '102 bytes', 等等)。#}
<p>{{ file_size|filesizeformat }}</p>
{#date:如果 value=datetime.datetime.now(),同上#}
{#slice:把字符串按照切片的功能进行切割显示(顾头不顾尾)#}
{{ str|slice:"2:-1" }}
{#truncatechars:如果字符串字符多于指定的字符数量,那么会被截断。截断的字符串将以可翻译的省略号序列(“...”)结尾(...也占3个字符)。 参数:要截断的字符数#}
<p>{{ text|truncatechars:20 }}</p>
{#truncatewords:按照单词截取#}
<p>{{ text|truncatewords:6 }}</p> {#safe:Django的模板中会对HTML标签和JS等语法标签进行自动转义;为了在Django中关闭HTML的自动转义有两种方式,如果是一个单独的变量我们可以通过过滤器“|safe”的方式告诉Django这段代码是安全的不必转义。#}
<p>{{ link }}</p>
{#浏览器效果:<a href='#'>click</a>#}
<p>{{ link|safe }}</p> {#add:加法;如下:让其加100#}
<p>{{ l.0|add:100 }}</p>
{#upper:转成大写#}
<p>{{ name|upper }}</p>
<hr> {#标签#}
{#for标签:遍历每一个元素#}
{#i就是l列表中的元素#}
{% for i in l %}
<p>{{ i }}</p>
{% endfor %}
{#可以利用{% for obj in list reversed %}反向完成循环。#} {#i是info字典中的每个key#}
{% for i in info %}
<p>{{ i }}</p>
{% endfor %}
{#遍历一个字典#}
{% for key,val in info.items %}
<p>{{ key }}:{{ val }}</p>
{% endfor %} {% for person in person_list %}
<p>{{ person.name }} {{ person.age }}</p>
{% endfor %} {#循环序号可以通过{{forloop}}显示;{{forloop}}必须要写在循环内部;forloop.counter是从1开始,forloop.counter0是从0开始 #}
{% for i in l %}
<p>{{ forloop.counter}} {{ i }}</p>
{% endfor %} {#for...empty:for 标签带有一个可选的{% empty %} 从句,以便在给出的组是空的或者没有被找到时,可以有所操作。#}
{% for i in empty_list %}
<p>{{ i }}</p>
{% empty %}
<p>内容为空</p>
{% endfor %}
{#如果empty_list为空,就会显示{% empty %}后面的 <p>内容为空</p> 标签#}
<hr>
{#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 %} {#with:使用一个简单地名字缓存一个复杂的变量,当你需要使用一个“昂贵的”方法(比如访问数据库)很多次的时候是非常有用的#}
{% with person_list.1.age as p_age %}
{# 此时 p_age 就代表 person_list.1.age #}
{{ p_age }}
{{ p_age }}
{% endwith %} {#csrf_token:这个标签用于跨站请求伪造保护#} </body>
</html>
templates/login.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<form action="" method="post">
{# csrf_token:这个标签用于跨站请求伪造保护;(可以给当前页面发送POST请求) #}
{% csrf_token %}
<input type="text" name="user">
<input type="submit">
</form> </body>
</html>
模板语法之自定义标签和过滤器
步骤:
- 在settings中的INSTALLED_APPS配置当前app,不然django无法找到自定义的simple_tag.
- 在app中创建templatetags模块(模块名只能是templatetags)
- 创建任意 .py 文件,如:my_tags.py;在其中定义自己的过滤器和标签
- 在使用自定义过滤器的html文件中导入之前创建的 my_tags.py
- 使用自定义的过滤器或标签
目录结构:
app01/views.py
from django.shortcuts import render # Create your views here. def index(request):
i = 10
return render(request,"index.html",locals())
app01/templatetags/my_tags_filters.py
from django import template register = template.Library() # register的名字是固定的,不可改变 @register.filter
def multi_filter(x,y):
return x*y
# 一个函数加上装饰器 register.filter 就变成了一个自定义的过滤器;上述过滤器实现的功能是两个数相乘
# 自定义的过滤器要在模板语法中使用
# 自定义过滤器的局限性:第一个形参是被修饰的变量,第二个形参是过滤器中的参数;过滤器最多只能放两个参数
# 自定义过滤器的优势:进行逻辑判断时,只能用过滤器 # 自定义标签
@register.simple_tag
def multi_tag(x,y):
return x*y
# 自定义标签无参数个数的限制
templates/index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<h3>自定义过滤器,标签</h3>
{#在使用自定义的过滤器的html文件中导入之前创建的 my_tags_filters.py#}
{% load my_tags_filters %}
<p>{{ i|multi_filter:20 }}</p>
{#函数multi_filter中有两个形参,所有过滤器multi_filter中要给一个参数,如上面的20#} {#调用自定义标签#}
<p>{% multi_tag 7 9 %}</p> {#自定义过滤器的优势#}
{#变量乘以20如果大于100就显示100,否则就显示它本身#}
{% if i|multi_filter:20 > 100 %}
<p>100</p>
{% else %}
<p>{{ i }}</p>
{% endif %}
{#自定义标签不能放到流程控制判断中#} </body>
</html>
模板继承(extends)
模版继承可以让你创建一个基本的“骨架”模版,它包含您站点中的全部元素,并且可以定义能够被子模版覆盖的 blocks 。
目录结构:
urls.py
from django.contrib import admin
from django.urls import path from app01 import views urlpatterns = [
path('admin/', admin.site.urls),
path(r'index/',views.index), path(r"orders/",views.orders)
]
views.py
from django.shortcuts import render # Create your views here. def index(request):
i = 10
return render(request,"index.html",locals()) def orders(request):
return render(request,"orders.html")
base.html (需要引入的模板样式;extends 语法)
<!DOCTYPE html>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8"> {#再放一个盒子用于重新写title标签;可留多个盒子用于以后扩写内容#}
{% block title %}
<title>base</title>
{% endblock %}
{# block区域里面本身也可以写内容,如上面的block写入 <title>base</base> ,这样如果引用这个模板时不重写 title这个block,就会默认会使用 block中原有的内容 #}
<link href="https://cdn.bootcss.com/bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet">
<style>
* {
padding: 0;
margin: 0;
} .header {
width: 100%;
height: 50px;
background-color: blue;
}
</style>
</head>
<body>
{#模板语法之继承#}
<div class="header"></div> <div class="container">
<div class="row">
<div class="col-md-3">
{# 想在这个地方调用advertise.html,就用include语法#}
{% include "advertise.html" %} </div>
<div class="col-md-9">
{# 继承:col-md-9 中的内容都删除#}
{# 在这个地方写一个 block,意味着在这留了一个区域等待别人来重新写 #}
{% block con %} {% endblock %}
</div> </div>
</div> </body>
</html>
orders.html(在其中引入 base.html 这个模板)
{#extends需要放在第一行#}
{#extends标签:用于继承;把 base.html 的样式全都拿过来(头部和左侧栏样式),然后 col-md-9中的内容自己再重新写#}
{% extends "base.html" %}
{#引入过来 base.html的样式之后,需要在 block中填充内容#}
{% block con %}
{# 重新写自己的内容 #}
<h4>订单</h4> {% endblock %} {#重新写title;放一个HTML的title标签#}
{% block title %}
<title>orders</title>
{% endblock %} {#过程:先通过 extends 来继承样式,再通过 block 来填充内容#}
{#继承用于解决HTML代码的复用性#}
index.html(include语法)
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<link href="https://cdn.bootcss.com/bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet">
<style>
* {
padding: 0;
margin: 0;
} .header {
width: 100%;
height: 50px;
background-color: blue;
}
</style>
</head>
<body>
{#模板语法之继承#}
<div class="header"></div> <div class="container">
<div class="row">
<div class="col-md-3">
{# 想在这个地方调用advertise.html,就用include语法#}
{% include "advertise.html" %} </div>
<div class="col-md-9">
<h3>自定义过滤器,标签</h3>
{#在使用自定义的过滤器的html文件中导入之前创建的 my_tags_filters.py#}
{% load my_tags_filters %}
<p>{{ i|multi_filter:20 }}</p>
{#函数multi_filter中有两个形参,所有过滤器multi_filter中要给一个参数,如上面的20#} {#调用自定义标签#}
<p>{% multi_tag 7 9 %}</p> {#自定义过滤器的优势#}
{#变量乘以20如果大于100就显示100,否则就显示它本身#}
{% if i|multi_filter:20 > 100 %}
<p>100</p>
{% else %}
<p>{{ i }}</p>
{% endif %}
{#自定义标签不能放到流程控制判断中#}
</div> </div>
</div> </body>
</html>
advertise.html(被 index.html引入的内容)
<div class="action">
<div class="panel panel-danger">
<div class="panel-heading">Panel heading without title</div>
<div class="panel-body">
111
</div>
</div>
<div class="panel panel-warning">
<div class="panel-heading">Panel heading without title</div>
<div class="panel-body">
222
</div>
</div>
<div class="panel panel-success">
<div class="panel-heading">Panel heading without title</div>
<div class="panel-body">
333
</div>
</div>
</div>
注意:
- 如果你在模版中使用
{% 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
标签。
Django:(2)视图层&模板层的更多相关文章
- Django 的路由层 视图层 模板层
--------------------------------------------------------------通过苦难,走向欢乐.——贝多芬 Django-2的路由层(URLconf) ...
- django 实战篇之模板层
模板层 {{}} 变量相关 {%%} 逻辑相关 前端获取容器类型的数据统一使用 句点符(.) 两种给模板传递值的方式 return render(request,'index.html ...
- 五、Django之视图和模板-Part 3
一.概述 一个视图就是一个页面,通常提供特定的功能,使用特定的模版.列如:在一个博客应用中,你可能会看到下列视图: 博客主页:显示最新发布的一些内容 每篇博客的详细页面:博客的永久链接 基于年的博客页 ...
- 3.Django| 视图层| 模板层
1.视图函数 文件在view_demo 一个视图函数简称视图,是一个简单的Python 函数,它接受Web请求并且返回Web响应.响应可以是一张网页的HTML内容,一个重定向,一个404错误,一个XM ...
- Django之深入了解模板层
目录 模板语法 模板传值 过滤器 标签 自定义过滤器和标签 模板继承 模板导入 模板语法 前端模板的语法只记住两种就行了. {{ xxx }} 变量相关的 { % % } 逻辑相关的 模板传值 我们通 ...
- Django之视图与模板以及在模板中使用bootstrap
从url中也可以传递参数给后台进行处理.比如http://127.0.0.1:8001/add/?a=4&b=5. 这个链接传入a=4,b=5.后台将进行a+b的处理 新增处理函数 def a ...
- Django框架之第五篇(模板层) --变量、过滤器、标签、自定义标签、过滤器,模板的继承、模板的注入、静态文件
模板层 模板层就是html页面,Django系统中的(template) 一.视图层给模板传值的两种方法 方式一:通过键值对的形式传参,指名道姓的传参 n = 'xxx'f = 'yyy'return ...
- 03_Django-GET请求和POST请求-设计模式及模板层
03_Django-GET请求和POST请求-设计模式及模板层 视频:https://www.bilibili.com/video/BV1vK4y1o7jH 博客:https://blog.csdn. ...
- Django-1版本的路由层、Django的视图层和模板层
一.Django-1版本的路由层(URLconf) URL配置(URLconf)就像Django所支撑网站的目录.它的本质是URL与要为该URL调用的视图函数之间的映射表:我们就是以这种方式告诉Dja ...
随机推荐
- 用代码设置 RelativeLayout.LayoutParams
1.注意 不能在RelativeLayout容器本身和他的子元素之间产生循环依赖,比如说,不能将RelativeLayout的高设置成为WRAP_CONTENT的时候将子元素的高设置成为 ALIGN_ ...
- 456 132 Pattern 132模式
给定一个整数序列:a1, a2, ..., an,一个132模式的子序列 ai, aj, ak 被定义为:当 i < j < k 时,ai < ak < aj.设计一个算法,当 ...
- poj3735Training little cats
链接 构造矩阵 快速幂求解 构造矩阵a[i]为每个cati所拥有的花生总数 这里多加一维用来求和,具体是怎么求得可以看下面的一组例子 假设有3个cat a[] = {1,0,0,0} 构造单位矩阵来保 ...
- Java-超市购物小票案例-详细介绍
1.1 超市购物购物小票需求分析 用户循环进行三个操作: 1.输入购买数量,代表为所购买货物的数量赋值,从而计算每项商品金额 2.打印小票,将已有数据打印 3.退出系统(因为该程序为循环操作,无法终 ...
- 前端缓存-IndexedDB
IndexedDB 就是浏览器提供的本地数据库,它可以被网页脚本创建和操作.IndexedDB 允许储存大量数据,提供查找接口,还能建立索引.这些都是 LocalStorage 所不具备的.就数据库类 ...
- (2) Tomcat启动Jenkins
Tomcat启动Jenkins 1. 下载Tomact,解压缩到指定目录. 2. 下载Jenkins.war文件,方到Tomact的WebApps下面即可. 3. 修改Tomcat的HTTP端口和默认 ...
- ssd训练自己的数据集
1.在ssd/caffe/data下创建VOC2007的目录,将ssd/caffe/data/VOC0712里的create_data.sh.create_list.sh和labelmap_voc.p ...
- vc++实现控制USB设备启用与否
#include <WINDOWS.H> #include <TCHAR.H> #include <SETUPAPI.H> //#in ...
- mvc core 中使用 redis
redis 下载安装路径: https://github.com/MicrosoftArchive/redis/releases 右键打开cmd命令行,运行命令: .\redis-server.e ...
- 【C语言】控制台窗口图形界面编程(七):鼠标事件
目录 00. 目录 01. INPUT_RECORD结构 02. MOUSE_EVENT_RECORD结构 03. ReadConsoleInput函数 04. 示例程序 00. 目录 01. INP ...