一、Django请求生命周期

1.路由层urls.py

Django 1.11版本 URLConf官方文档

1.1 urls.py配置基本格式

from django.conf.urls import url

urlpatterns = [
url(正则表达式, views视图函数,参数,别名),
]

1.11.x版本默认

from django.conf.urls import url

urlpatterns = [
url(r'^admin/', admin.site.urls),
url(r'^test/$', views.test),
] 
# 获取到用户输入的url后,根据正则匹配是否对应
# http://127.0.0.1:8000/test 请求的时候实际是请求了2次,第一次请求是按照浏览器输入的进行请求,但是没有匹配到,第二次请求浏览器会自动在末尾加一个/之后进行匹配,如果还匹配不上直接报错
# 注意事项
1 urlpatterns中的元素按照书写顺序从上往下逐一匹配正则表达式,一旦匹配成功则不再继续。
2 若要从URL中捕获一个值,只需要在它周围放置一对圆括号(分组匹配)。
3 不需要添加一个前导的反斜杠,因为每个URL 都有。例如,应该是^articles 而不是 ^/articles。
4 每个正则表达式前面的'r' 是可选的但是建议加上。
urlpatterns = [
url(r'^admin/', admin.site.urls),
# url(r'test/[0-9]{4}/$', views.test),
# 无名分组:会将分组内的结果 当做位置参数自动传递给后面的视图函数views.py
url(r'test/([0-9]{4})/$', views.test),
# url(r'^test/(\d+)/$',views.test),
# 有名分组:会将分组内的结果 当做关键字参数自动传递给后面的视图函数
url(r'^testadd/(?P<id>[0-9]{4})/$',views.testadd),
]
# 无名分组:http://127.0.0.1:8000/test/3333/,视图函数加参数后可以访问,如果不加会提示test() takes 1 positional argument but 2 were given
# 有名分组

 1.2 反向解析

  根据别名动态解析出可以匹配上视图函数之前的url的一个结果(注意:在起别名的时候,一定要保证 所有的别名都不能重复,必须是唯一的)

# urls.py
url(r'^testxxx/',views.test,name='t')
url(r'^test/(\d+)/$',views.test,name='ttt'), # 前端
没有正则表达式的反向解析
{% url 't' %}
无名分组反向解析
有名分组同上
   有正则表达式的反向解析
   {% url 'ttt' 1 %} # 数字通常是数据库中字典的pk值 # 后端
from django.shortcuts import render,HttpResponse,redirect,reverse
没有正则表达式的反向解析
reverse('t')
   无名分组反向解析
reverse('ttt',args=(1,)) #有正则表达式的反向解析函数视图views.py
有名分组同上 # urls.py中使用别名后,testxxx无论怎么变,浏览器中路径也会自动变化,动态解析到前端

有名分组和无名分组能否混合使用?
---有名无名不能混合使用!!!

1.3 页面伪静态

# 伪静态
让一个动态页面伪装成一个看似数据已经写死了的静态页面,其实是经过了视图函数处理,动态渲染的页面
好处:让搜索引擎加大对你这个页面的收藏力度,当别人搜索你这个页面相关内容,提高优先展示概率(花钱最好)
加大seo查询

# 例如:在urls.py中将路由设置成,视图函数views.py中还是不变:return HttpResponse("index.html")
url(r'^index.html$',views.index),
例如:10982293.html https://www.cnblogs.com/Dominic-Ji/articles/10982293.html

 1.4 django版本区别1.x与2.x

1.X
路由里面用的是url()
2.X
路由里面的用的是path()
url第一个参数放的是正则表达式
而你的path第一个参数写什么就是什么,不支持正则
如果你还想使用第一个参数是正则的方法
django2.X版本中有一个叫re_path()
ps:2.x中re_path就等价于1.x中的url # 虽然path不支持正则表达式,但是它提供了五种转换器(了解)

1.5 路由分发

    当一个django项目下面有多个app的情况下,总的urls.py中路由与视图函数的对应关系太多 不便于管理
这个时候就可以再每个app下创建自己的urls.py,总的urls.py不再做对应关系,而只是做分发任务
每个app下都可以有自己的urls.py static文件夹 templates模板文件,也就意味着 每个app都可以被独立的开发出来 而不需要讨论交互
#  路由分发:根据前缀,去对应的目录下查找路由

# 总路由下urls.py配置
# 重名的使用别名
from django.conf.urls import url,include
from app01 import urls as app01_urls
from app02 import urls as app02_urls urlpatterns = [
url(r'^admin/', admin.site.urls),
url(r'^app01/',include(app01_urls)),
url(r'^app02/',include(app02_urls)),
] # 应用app01下的路由
from django.conf.urls import url
from app01 import views urlpatterns = [
url(r'^urlindex',views.urlindex),
] # app01下的视图函数views.py
from django.shortcuts import render,HttpResponse,redirect def urlindex(request):
return HttpResponse("app01下的index") # 应用app02下的路由
from app02 import views urlpatterns = [
url(r'^urlindex',views.urlindex)
] # app02下的视图函数views.py
from django.shortcuts import render,HttpResponse,redirect def urlindex(request):
return HttpResponse("app02下的urlindex") # 访问app01下的链接:http://127.0.0.1:8000/app01/urlindex
# 访问app02下的链接:http://127.0.0.1:8000/app02/urlindex
# 都可以显示对应的提示

# 如果2个app下起了相同的名字,那么反向解析不支持自动查找应用前缀,需要了解名称空间的概念
# app01
urlpatterns = [
url(r'^urlindex',views.urlindex,name='aaa')
]
# app02
urlpatterns = [
url(r'^urlindex',views.urlindex,name='aaa')
]
# views.py中都打印下print('aaa')
# 访问app01和app02的urlindex后端打印的都是一样的 # 第一种方法:
# 反向解析的时候可以在name='aaa'中添加前缀解决
# 例如:name='app01_aaa' # 第二种方法:
# 名称空间(了解既可):在分发的时候再起一个名字
# 总路由urls.py中
urlpatterns = [
url(r'^app01/',include(app01_urls,namespace='app01')),
url(r'^app02/',include(app02_urls,namespace='app02')),
] #app01中的路由urls.py
urlpatterns = [
url(r'^urlindex',views.urlindex,name='aaa')
]
# app01的views.py
def urlindex(request):
print(reverse('app01:aaa'))
return HttpResponse("app01下的index")
# app02的路由
urlpatterns = [
url(r'^urlindex',views.urlindex,name='aaa')
]
# app02的views.py
def urlindex(request):
print(reverse('app02:aaa'))
return HttpResponse("app02下的urlindex") # 然后分别访问就正常了

# 使用importlib方法:

urlpatterns = [
# path('admin/', admin.site.urls),
path('home/', views.home),
path('news/<int:nid>/edit/', views.news),
path('article/', views.article),
] # int 整数
path('news/<int:nid>/edit/', views.news),
http://127.0.0.1:8000/news/1/edit/ # str 字符串
path('news/<str:nid>/edit/', views.news),
http://127.0.0.1:8000/news/s1/edit/
# slug 字母+数字+下划线+-
# uuid uuid格式,随机生成命令 uuid.uuid4()
# path 路径
path('news/<path:nid>/edit/', views.news),
http://127.0.0.1:8000/news/s1/ss/edit/

2. 视图层

2.1 JsonResponse

# views.py
import json
def index(request):
d = {'name':'simon','password':'123','hobby':'读书'}
# 前端不支持字典,需要转成json格式
return HttpResponse(json.dumps(d,ensure_ascii=False))
# 前端页面显示:http://127.0.0.1:8000/index/
{"name": "simon", "password": "123", "hobby": "读书"} # 第二种方式:
from django.http import JsonResponse
def index(request):
d = {'name':'simon','password':'123','hobby':'读书'}
# 前端不支持字典,需要转成json格式
# return HttpResponse(json.dumps(d))
return JsonResponse(d) # JsonResponse直接转换成json格式
# 前端没显示中文,可以通过JsonResponse源代码来看方法
# return JsonResponse(d,json_dumps_params={'ensure_ascii':False})

2.2 FBV与CBV

FBV function based views

CBV class based views

# views.py
from django.views import View
class MyLogin(View):
def get(self,request):
return HttpResponse("Get") def post(self,request):
return HttpResponse("Post") # urls.py中如何添加路径?
# CBV路由配置
url(r'^login/',views.MyLogin.as_view()), # 可以在前端home.html写一个页面测试post提交方式
<form action="/login/" method="post">
<input type="submit">
</form> # 可以看到我们访问login直接返回Get
# 访问home.html点击提交就会跳到login页面显示post
# 可以看到get请求来走get,post请求走post

3.模板层

模板语法--模板传值

# 模板语法 url.py
url(r'^demo/',views.demo),
# views.py
def demo(request):
i = 1
f = 1.11
s = 'hello'
# s = []
l = [1,2,3,4,5,6,7,8,9]
t = (1,2,3,4)
d = {'name':'simon','password':'123'}
se = {1,2,3,4}
# 通过字典传值方式
# return render(request,'demo.html',{'xxx':[1,2,3,4]}) def foo():
print("foo")
return "0000000oooooooooo" class Demo(object):
def index(self):
return 'index' @classmethod
def login(cls):
return 'cls' @staticmethod
def reg():
return 'reg' obj = Demo()
return render(request,'demo.html',locals()) # locals 会将所在名称空间中的所有名字全部传递给前端页面 # 前端页面
# 第一种传值方式
return render(request,'demo.html',{'xxx':[1,2,3,4]})
# 前端使用
{{ xxx }} # 第二种传值方式
# locals 会将所在名称空间中的所有名字全部传递给前端页面
return render(request,'demo.html',locals())
# 前端页面需要将所有定义的:i f s等使用双大括号括起来显示
# 如果是函数传到前端显示
<p>{{ foo }} 如果是函数名,传递到前端会自动加()调用,将调用后的结果展示到前端页面</p>
#如果是类
{#<p>{{ obj.index }} 只要是方法 都会自动加括号调用</p>#}

# 获取列表字典中某一个值
前端{{ l.0 }} or {{ d.name }}

 3.1.过滤器

# 后端3中demo类中直接定义n和i
import datetime
ctime = datetime.datetime.now()
sss = 'sadfasf sdfasf fasdfsadf sdfa' # 前端:
{{i|add:19}} # 结果:20
{{n|filesizeformat}} # n的值进行转化成文件大小M、G等
{{ ctime|date:'Y-m-d' }} # 日期获取
{{ sss|truncatechars:20 }} # 截断一部分...来省略(20包含3个点)
{{ sss|truncatewords:2 }} # 截断,只识别空格
#后端
def demo(request):
h = "<h1>我是h1标签</h1>"
s1 = "<script>alter(123)</script>"
# 后端转义views.py
from django.utils.safestring import mark_safe
s2 = "<h2>我是h2标签</h2>"
s2 = mark_safe(s2) # 这样前端就不需要用safe了 # safe告诉前端我这个代码是安全的,可以渲染
# 前端转义
{{ h|safe }}
{{ s1 }} # 这个如果加safe,前端就会死循环
{{ s2 }}

3.2 标签

# 后端
def demo(request):
l = [1,2,3,4,5,6,7,8,9]
s3 = [1,2]
s4 =[None,1] # 模板语法的if判断
# 前端demo.html
{% if s3 %}
<p> 有值{{ s3 }}</p> # 返回结果就是这个了
{% else %}
<p>这个东西是空的</p>
{% endif %}
{% if s4.0 %}
<p> 有值{{ s4 }}</p>
{% elif s4.1 %}
<p>没值</p>
{% else %}
<p>这个东西是空的</p>
{% endif %}
# 就算值取不到也不会报错 {% for foo in l %}
{# # foo为每次列表循环的元素,first为第一个值,last为最后一个值,中间可以#}
{% if forloop.first %}
<p>first...</p>
{% elif forloop.last %}
<p>这是last</p>
{% else %}
<p>继续啊~~~</p>
{% endif %}
{% empty %}
<p>是空的,不能循环</p>
{% endfor %}

3.3 模板的继承与导入

# 模板的继承
# 在你想做成模板的页面上 添加block块儿 来标识其他用户可以占用的区域
{% extends 'tmp.html' %} {% block content %}
<div class="jumbotron">
<h1>Hello, world!</h1>
<p>...</p>
<p><a class="btn btn-primary btn-lg" href="#" role="button">Learn more</a></p>
</div>
{% endblock %}
# 先在模板中划定区域,之后子板利用block就能够找到模板中可以被使用的区域 # 通常情况下 模板中最少有三个区域
css
content
js
ps:模板中的block块儿越多 页面的可扩展性越高
# 模板的导入
将一块html页面作为模块的方式 导入使用
{% include 'goodpage.html' %}
将goodpage.html页面内容直接导入到该语句的位置
# 模板的继承与导入
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script src="https://cdn.bootcss.com/jquery/3.4.0/jquery.min.js"></script>
<link href="/static/bootstrap-3.3.7/css/bootstrap.min.css" rel="stylesheet">
<script src="/static/bootstrap-3.3.7/js/bootstrap.min.js"></script>
</head>
<body>
<nav class="navbar navbar-default">
<div class="container-fluid">
<!-- Brand and toggle get grouped for better mobile display -->
<div class="navbar-header">
<button type="button" class="navbar-toggle collapsed" data-toggle="collapse"
data-target="#bs-example-navbar-collapse-1" aria-expanded="false">
<span class="sr-only">Toggle navigation</span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
</button>
<a class="navbar-brand" href="#">Brand</a>
</div> <!-- Collect the nav links, forms, and other content for toggling -->
<div class="collapse navbar-collapse" id="bs-example-navbar-collapse-1">
<ul class="nav navbar-nav">
<li class="active"><a href="#">Link <span class="sr-only">(current)</span></a></li>
<li><a href="#">Link</a></li>
<li class="dropdown">
<a href="#" class="dropdown-toggle" data-toggle="dropdown" role="button" aria-haspopup="true"
aria-expanded="false">Dropdown <span class="caret"></span></a>
<ul class="dropdown-menu">
<li><a href="#">Action</a></li>
<li><a href="#">Another action</a></li>
<li><a href="#">Something else here</a></li>
<li role="separator" class="divider"></li>
<li><a href="#">Separated link</a></li>
<li role="separator" class="divider"></li>
<li><a href="#">One more separated link</a></li>
</ul>
</li>
</ul>
<form class="navbar-form navbar-left">
<div class="form-group">
<input type="text" class="form-control" placeholder="Search">
</div>
<button type="submit" class="btn btn-default">Submit</button>
</form>
<ul class="nav navbar-nav navbar-right">
<li><a href="#">Link</a></li>
<li class="dropdown">
<a href="#" class="dropdown-toggle" data-toggle="dropdown" role="button" aria-haspopup="true"
aria-expanded="false">Dropdown <span class="caret"></span></a>
<ul class="dropdown-menu">
<li><a href="#">Action</a></li>
<li><a href="#">Another action</a></li>
<li><a href="#">Something else here</a></li>
<li role="separator" class="divider"></li>
<li><a href="#">Separated link</a></li>
</ul>
</li>
</ul>
</div><!-- /.navbar-collapse -->
</div><!-- /.container-fluid -->
</nav>
<div class="container-fluid">
<div class="row">
<div class="col-md-3">
<div class="list-group">
<a href="/loginn/" class="list-group-item active">登录</a>
<a href="/register/" class="list-group-item">注册</a>
<a href="#" class="list-group-item">Morbi leo risus</a>
<a href="#" class="list-group-item">Porta ac consectetur ac</a>
<a href="#" class="list-group-item">Vestibulum at eros</a>
</div>
</div>
<div class="col-md-9">
{% block content %}
<div class="jumbotron">
<h1>Hello, world!</h1>
<p>...</p>
<p><a class="btn btn-primary btn-lg" href="#" role="button">Learn more</a></p>
</div>
{% endblock %}
</div>
</div> </div>
</body>
</html> # login.html 模板的导入
{% extends 'tmp.html' %} {% block content %}
<h3>登录</h3>
<form action="" method="post" class="form-group">
<p>username:<input type="text" class="form-control"></p>
<p>password:<input type="text" class="form-control"></p>
<input type="submit" class="btn btn-danger pull-right">
</form>
{% endblock %} # reg.html模板的导入与继承
{% extends 'tmp.html' %} {% block content %}
{# 模板的导入#}
{% include 'good.html' %}
<h3 class="text-center">注册</h3>
<form action="" method="post" class="form-group">
<p>username:<input type="text" class="form-control"></p>
<p>password:<input type="text" class="form-control"></p>
<input type="submit" class="btn btn-danger pull-right">
</form>
{% endblock %}

Django之路由层、视图层、模板层介绍的更多相关文章

  1. day 45 Django 的初识2 路由层,视图层,模板层

    前情提要: 今天继续学习Django 的内容, 今天主要和渲染相关 1>配置路由 >2:写函数 >3 指向url 一:路由层 1:配置静态支持文件 1:路由层的简单配置 >dj ...

  2. 模板层语法、模板层之标签、模板的继承与导入、模型层之ORM常见关键字

    模板层语法.模板层之标签.模板的继承与导入.模型层之ORM常见关键字 一.模板层语法 1.模板语法的传值 urls代码: path('modal/', views.modal) views代码: de ...

  3. Web框架之Django_03 路由层了解(路有层 无名分组、有名分组、反向解析、路由分发 视图层 JsonResponse,FBV、CBV、文件上传)

    摘要: 路由层 无名分组 有名分组 反向解析 路由分发 名称空间 伪静态网页.虚拟环境 视图层 JsonResponse FBV 与 CBV(function base views与class bas ...

  4. django 实战篇之视图层

    视图层(views.py) django必会三板斧 HttpResponse >>> 返回字符串 render >>> 支持模板语法,渲染页面,并返回给前端 red ...

  5. django之视图层和部分模板层

    视图层 小白必会三板斧(三个返回的都是HttpResponse对象,通过看源码,可以知道是内部实现) 1.HttpResponse # 返回字符串 2.render # 返回一个html页面 还可以给 ...

  6. Django之深入了解视图层

    目录 视图层三板斧 HttpResponse render redirect JsonResponse FBV CBV CBV源码 如何给FBV和CBV加装饰器 视图层三板斧 规定视图函数必须有一个返 ...

  7. Django的View(视图层)

    目录 Django的View(视图层) 一.JsonResponse 二.后端接收前端的文件 三. FBV和CBV(源码分析) 四.settings.py配置文件源码分析 五. 请求对象(HttpRe ...

  8. Django学习---路由url,视图,模板,orm操作

    Django请求周期 url ->  路由系统  ->函数或者类 -> 返回字符串 或者 模板语言 Form表单提交: 点击提交 -> 进入url系统  ->  执行函数 ...

  9. 052.Python前端Django框架路由层和视图层

    一.路由层(URLconf) 1.1 路由层简单配置 URL配置(URLconf)就像Django 所支撑网站的目录.它的本质是URL与要为该URL调用的视图函数之间的映射表:你就是以这种方式告诉Dj ...

  10. [Django框架之视图层]

    [Django框架之视图层] 视图层 Django视图层, 视图就是Django项目下的views.py文件,它的内部是一系列的函数或者是类,用来专门处理客户端访问请求后处理请求并且返回相应的数据,相 ...

随机推荐

  1. 工作记录:Vue3.0新特性

    简单对比 Vue2.x 与 Vue3.x 响应式 Vue2 使用Object.defineProperty劫持对象的属性 Vue3 使用Proxy 直接代理对象 由于Object.defineProp ...

  2. CDC报错:invalid value null used for required field "null"

    原因:数据库ceate_time时间字段设置为not null ,但是没有设置default值解决办法:1.修改ceate_time字段可以为null,即去掉 `create_time` dateti ...

  3. 为什么医疗保健需要MFT来帮助保护EHR文件传输

    毫无疑问,医疗保健行业需要EHR技术来处理患者,设施,提供者等之间的敏感患者信息.但是,如果没有安全的MFT解决方案,您将无法安全地传输患者文件,从而使您的运营面临遭受数据泄露,尴尬,声誉损失以及随之 ...

  4. 基于 alientek rv1126 快速启动调试那的写坑

    基于 alientek rv1126 快速启动调试那的写坑 1. sdk 编制准备工作 1.1 编译配置修改 首先拿到 sdk 通过修改一下相关配置 1.1.1修改DDR 配置 cd /home/al ...

  5. Unity最新一键清理Prefab中所有MissingComponent

    因为老的API  Properties.DeleteArrayElementAtIndex(propertyIndex);提示没权限修改, 而unity提供了新的API  GameObjectUtil ...

  6. #主席树,并查集#CodeChef Sereja and Ballons

    SEABAL 分析 考虑用并查集维护当前连续被打破的气球段,那么每次新增的区间就是 \([l_{x-1},x]\) 到 \([x,r_{x+1}]\) 的连接. 只要 \(l,r\) 分别满足在这之间 ...

  7. #原根,BSGS,扩欧,矩阵乘法#CF1106F Lunar New Year and a Recursive Sequence

    题目 已知数列 \(f\) 满足 \(f_{1\sim k-1}=1\) 且 \(f_n=m\), 并且知道 \(f_i=(\prod_{j=1}^kf_{i-j}b_j)\bmod{99824435 ...

  8. #SPFA#洛谷 4042 [AHOI2014/JSOI2014] 骑士游戏

    题目 分析 如果我想普通攻击1,那么必须干掉所有产生的其它怪兽,这不由得可以用一个不等式来表示, \(普攻+\sum need<法攻\) 但是所需要消灭的怪兽同样可以这样进行,所以它可能具有后效 ...

  9. 你真的了解java class name吗?

    在面向对象的世界,Class是java的基础.java.lang.Class实际上是继承自java.lang.Object. class有一个方法叫做getName,该方法会返回(class, int ...

  10. 1.NCC算法实现及其优化[基础实现篇]

    NCC算法实现及其优化 本文将集中探讨一种实现相对简单,效果较好的模板匹配算法(NCC) \[R(x,y)= \frac{ \sum_{x',y'} (T'(x',y') \cdot I'(x+x', ...