一、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. 记录--卸下if-else 侠的皮衣!- 策略模式

    这里给大家分享我在网上总结出来的一些知识,希望对大家有所帮助 当我是if-else侠的时候 怕出错 给我一个功能,我总是要写很多if-else,虽然能跑,但是维护起来确实很难受,每次都要在一个方法里面 ...

  2. linux 时钟同步

    yum install ntp -y #cn.pool.ntp.org ntp[1-7].aliyun.com ntpdate ntp1.aliyun.com #把当前系统时间写入到CMOS中 clo ...

  3. opensips的dispatcher模块笔记

    操作系统 :CentOS 7.6_x64 opensips版本:2.4.9 dispatcher模块模块实现了基于目的地址的调度功能,可用作无状态负载均衡,但不能保证均匀分配.今天整理下CentOS7 ...

  4. MySQL配置和常用命令

    目录 数据库配置 常用操作 项目地址:https://github.com/aijisjtu/Bot-Battle graph LR A[配置数据源] --> B[建立连接] B --> ...

  5. 直播预告丨 OpenHarmony 标准系统多媒体子系统之相机解读

    5 月 26日(周四)晚上 19 点,OpenHarmony 开源开发者成长计划知识赋能第五期"掌握 OpenHarmony 多媒体的框架原理"的第六节直播课,即将开播! 深开鸿资 ...

  6. HTML基础之input系列

    <form action=""> <div> 用户名:<input type="text" name="user&quo ...

  7. 粗心的小红qsnctfwp

    将原 apk 安装包后缀名修改为 zip 将其中的 classes3.dex 文件解压 使用 Notepad++ 或其他工具打开 classes3.dex,将第 2 行的 38 修改为 35 或 36 ...

  8. 基于openstack安装部署私有云详细图文教程

    本文主要分享的是云计算.openstack的使用.私有云平台建设.云服务器云硬盘的构建和使用.从基本概念入手到私有云建设,信息量非常大.对于openstack的安装部署都是从官方文档中一步步的介绍,内 ...

  9. CentOS下修改 MySQL 的密码

    做服务器运维,修改 MySQL 的密码是经常的需要,定期修改 MySQL 密码是网站安全的一个保证.这里记录一下修改 MySQL 密码的一些命令,方便以后查看. 修改root密码 CentOS 下 M ...

  10. 重新点亮shell————awk数组[十四]

    前言 简单介绍一下awk的数组. 正文 数组的定义: 数组的遍历: 删除数组: 例子: 例子2: 结 下一节awk函数.