路由系统和模板基础
Posted bianyimaomaochong
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了路由系统和模板基础相关的知识,希望对你有一定的参考价值。
1. url的复习
网址 全球统一资源定位符
格式 协议(http,HTTPS,ftp等)+域名(ip地址和端口)+路径+参数
2.django的路由系统
当一个请求来到时
1.首先到项目目录下的urls.py (根URLconf模块)中,查找路由规则
2.根URLconf模块,里面定义了 urlpatterns 变量
3.urlpatterns 是一个(django.urls.path,django.urls.re_path 对象)列表 其中django.urls.path和django.urls.re_path都是django中的方法
4.按顺序运行每个url模式,在第一个匹配的模式停止
5.一旦匹配,django导入并调用给定的视图
6.如果中间出错,或者没有匹配到,返回404
-path(route, view, kwargs=None, name=None)
- route 是一个字符串的url规则
- view 是个视图,表示给定的路径会调用的视图,写上调用的方法,不要加括号
- kwargs 不是不定长参数,而是额外参数,传递给view,必须是一个字典
- name url的命名
前两个参数是必须的
- 在url中捕获参数
在url规则中使用`<变量名>`可以捕获url中的值,注意是写在前边的route里,路径后边比如‘detail/<变量名>/‘,url的route里的参数,要和views里的方法里的参数一 一对应,
urlpatterns = [ path(‘home/‘, views.index, name=‘index‘), path(‘detail/<int:pk>/‘, views.detail, kwargs={‘status‘: True}), re_path(r‘students/(?P<year>d{4})/(?P<month>[0-9]|1[0-2])/‘, views.students), path(‘login/‘, views.login) ]
多个参数 1)views.py中的函数里,加上其他参数,在urls中的路由方法里,detail/<变量名1>/<变量名2>/,变量1,2的顺序可以换,但是访问页面的时候在浏览器中传参要按照urls中设置的顺序
2)参数之间也可以不用/,可以用连接符-,访问网页的时候在浏览器中输入的url的参数之间也要用连接符,别的符号链接也可以,比如+,~,,(注意这里,也可以),.,[等
def detail(request,pk,status):#pk是主键 return HttpResponse("离开学还有%s天,你作业做完没,道路千万条,学习第一条,作业没写完,开学两行泪!" % pk) def students(request,year,month): return HttpResponse("%s年%s月报名的学生列表" % (year, month))
传递给视图 ,匹配了url之后调用视图的时候传递给视图的是关键字参数,url路径中不分组则按照位置参数传
** 捕获的值是 字符串 url中域名后边的东西,会被传递到urls的urlpatterns里边对应的路径方法中,
- 路径转换器 限制传递进来的参数,也是写在urlpatterns里的路径里,它限制了url传进来的参数,必须是路径转换器设置的数据类型(试过了能转换成该类型的数据类型也不可以,必须得是那个数据类型),并且从路径传给视图的参数的类型就是路径中规定的数据类型
案例:<int:pk>
path(‘detail/<int:pk>/‘, views.detail, kwargs={‘status‘: True}),
常用的转换器:
- str 匹配除了‘/‘路径分隔符之外的所有字符串
- int 匹配任意整数
- slug 匹配任意ascii字符 加上连字符和下划线
- uuid 格式化id,通用唯一识别码(Universally Unique Identifier)的缩写UUID是指在一台机器上生成的数字,
它保证对在同一时空中的所有机器都是唯一的。通常平台会提供生成的API。按照开放软件基金会(OSF)制定的标准计算,用到了以太网卡地址、纳秒级时间、芯片ID码和随机数。
- path 匹配任意非空字符
- 使用正则表达式 re_path(route, view, kwargs=None, name=None),首先要导入re_path()模块,写在上边的from django.urls import path的path后面就可以了
在views里和上面一样,在浏览器中输入url时,参数也是那样传递,
在urlpatterns里面,方法不是path(),要用re_path(),第一个参数的引号前加r,r""
python 中 正则表达式的分组命名 (?<name>pattern) 具体例子是r‘(?P<year>d{4})‘或者4个d,然后/(?P<month>[0-9]|1[0-2])/,连起来就是re_path(r‘(students/(?P<year>d{4})/(?P<month>[0-9]|1[0-2])/‘,views.students)
re_path(r‘students/(?P<year>d{4})/(?P<month>[0-9]|1[0-2])/‘, views.students),
- django 搜索 url 搜索的是什么?
只搜索路径部分,跟参数,以及请求方法(get,post)无关
同一个url 可以匹配 get, post
- 包含其他URLconfs:一般很少把视图函数写在公共的项目文件夹下,一般写在app里,如何指定app中的路径,需要在app中新建urls.py,然后在项目文件夹的urls.py中
include: 1)导入:在导入path和re_path后加上include
2)项目中的urls去定义app中的urls :在项目文件夹的urls.py中的urlpatterns加上path("appname/",include(‘appname.urls‘)),
注意include里的文件名后面的.urls是你在app文件夹中创建的那个,也可以不叫urls,但是最好叫urls,appname.urls要加引号括起来
3)在app的urls.py中的urlpatterns中,先导入:from django.urls import path,re_path后加上include,以及from . import views
4)定义path()或re_path(),视图函数的相对路径也是和urls文件平级的
5)运行后浏览器访问的时候url中的路径 要先写appname然后/app中的视图函数
原理,访问的时候url先经过根urls.py,匹配到appname,先切掉appname的部分,剩下的传到include里边的appname.urls里,在那里面匹配剩下的,
前边的路由如果传进来参数,也是可以传递到include里边的,在include里边对应的app.urls中继续匹配路径,匹配到之后传递给app中相应的视图函数,
这样在根urls中设置了"appname-<参数>/"会传给app中的每个路径,如果在相应app的视图函数中没有参数接收他就会报错
- 传递额外参数
1path,re_path 方法中,传递一个kwargs 的字典参数,传递给视图函数,不能urls中定义了额外参数而在视图函数中没有参数接收他
2***** 当kwargs 中的key 与 url捕获中的key 一致的时候,以kwargs为准,比如path(‘detail/<int:pk>/‘,views.detail,kwargs={‘pk‘:10}),如果访问网址中输入别的数字,最终传给视图函数的还是10
3如果在项目文件夹的urls中的include路径中加上kwargs={‘somekey‘:"somevalue"},就会把这个额外参数传递给该app的每个视图函数,相当于给app中的urls中的每个路径加上kwargs={‘somekey‘:"somevalue"}
path(‘detail/<int:pk>/‘, views.detail, kwargs={‘status‘: True}),
- url 命名
页面重定向 ,跳转页面(响应状态码301) 登录之后, 某个操作之后,django中提供了一个方法redirect,能接收url,返回一个重定向的响应,然后页面就会重定向
比如在视图函数中,return redirect(‘http://www.baidu.com‘)返回重定向的url,也就是在访问该视图时,会自动重定向到指定的url,可以用于登陆页面,
redirect中也可以“/appname/index/”这里要把相对路径写全,前边也要有/,后面也要有/,但是如果想给路由中的url路径改名,重定向的地方都要改,这样是硬编码,url命名是为了避免硬编码
在urls.py中urlpatterns中的指定path中加一个name参数 给改名后的url起个名字
path(‘home/‘, views.index, name=‘index‘),
再在views.py中导入reverse方法,就可以通过这个url的名字反向的解析路由,解析出url,导入后在视图函数中加上url = reverse(‘index‘),返回时return redirect(url),这时候reverse方法会把该url反向解析成urls中给定的path中的全路径
from django.shortcuts import render,redirect,reverse def login(request): url = reverse("app1:index") return redirect(url)
- app_name 同一项目下app名不能重复
定义在 app文件夹下的urlconf模块中,就是每个app文件夹下urls.py里,都分别加上app_name = app名称,
app_name = ‘app1‘
然后在各自views里的reverse(‘appname:index‘)
def login(request): url = reverse("app1:index") return redirect(url)
如果有多个app都有同名的跳转,则根目录解析时候会调用最后一个include的视图函数,所以必须给每个app起名字
3. 模板系统
html 源码写到模板文件中
- 模板路径设置
1)一般模板是放在项目的根目录下的,新建一个templates文件夹,然后配置settings.py
2)settings里面设置 TEMPLATES,这是一个dict:
‘BACKEND‘:‘django.template.backends.django.DjangoTemplates‘是模板的引擎,是后台
‘DIRS’:[]是模板的路径,模板渲染的设置就是要搞它,
3)先在settings.py中导入os模块,注意settings.py有一行BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) 用来取到项目的根目录
4)在 TEMPLATES中的DIRS这个键的值的列表里边,添加拼接路径os.path.join(BASE_DIR,‘templates‘)告诉django模板从这个文件夹里找,动态获取templates文件夹的路径,
‘DIRS‘: [os.path.join(BASE_DIR,‘templates‘)],
如果打印os.path.join(BASE_DIR,‘templates‘),得到的是从home目录开始到templates的绝对路径
其实放模板的文件夹起其他名字也可以,但是起好名字settings里设置的时候就要用它,不要写错
5)在templates文件夹中,为想添加模板的app设置各自的文件夹,比如新建一个teacher文件夹,然后在这个文件夹里新建HTML File文档,命名index,编写前端代码
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>app1_index</title> </head> <body> <h1>我是app1中的主页面</h1> <form action=""> <p>用户名: <input type="text"></p> <p>密码: <input type="password"></p> <p><input type="submit" value="登陆"></p> </form> </body> </html>
6)在指定的视图中想拿到为它编写的模板 首先from django.template.loader import get_template
7) 在指定的视图函数中定义tp = get_template(‘teacher/index.html‘)也就是说templates不用写,从它里边的路径开始写到想要的html文件就可以,django会默认帮我们把前边路径补上
8)渲染模板 html = tp.render() render是调用的方法,得到的是一个模板所定义的html文档的一整个字符串
9)将html返回出去 return HttpResponse(html)
10)推荐使用快捷方式:省掉步骤从7到9,直接return render(request,‘teacher/index.html‘)
def index(request): return render(request, ‘app1/html1.html‘)
以上是关于路由系统和模板基础的主要内容,如果未能解决你的问题,请参考以下文章