一.概念及基本语法
1.概念
视图函数是MTV中的View,相当于MVC中的Controller作用,控制器接收用户输入(请求),协调模板模型,对数据进行处理,负责模型和模板的数据交互。
视图函数返回值类型:
(1)以Json数据形式返回
前后端分离
return JsonResponse
(2)以网页的形式返回 HttpResponse render redirect
重定向到另一个网页
错误视图(40X,50X)
2.url路由匹配规则
配置好django的基本环境后,创建子路由:
urlpatterns = [
url(r'^haha', views.haha),
url(r'^hahaha', views.hahaha),
]
生成的视图函数:
def haha(request):
return HttpResponse('haha')
def hahaha(request):
return HttpResponse('hahaha')
如果在网页上输入haha或者hahaha路径会有怎样的结果 ???
结果发现,不同的路径却有相同的结果,都是调用haha函数,而没有调用hahaha函数。
假设我们将它们位置换一下:
urlpatterns = [
url(r'^hahaha', views.hahaha),
url(r'^haha', views.haha),
]
再次运行,查看结果:
这时发现可以得到各个结果,这时为什么呢???
实际上,这有关优先匹配,匹配到就停止了。
url匹配正则注意事项:
正则匹配时从上到下进行遍历,匹配到就不会继续向后查找了
匹配的正则前方不需要加反斜线
正则前需要加(r)表示字符串不转义
一般我们会加‘/’,来精确匹配,避免出现上面的矛盾。
url匹配规则:按照书写顺序,从上到下匹配,没有最优匹配的概念,匹配到就停止了。
urlpatterns = [
url(r'^haha/', views.haha),
url(r'^hahaha/', views.hahaha),
]
运行结果:
3.路由参数
(1)基本使用
如何在路径后面加参数,并获取到参数???
urlpatterns = [
url(r'^testRoute/(\d+)/',views.testRoute),
]
视图函数:
def testRoute(request, id):
print(id)
print(type(id))
return HttpResponse('testRoute')
运行结果:
总结:
路由路径是如果有/了,那么是精确匹配,匹配到了就不管后面的是否准确
路由参数使用正则接收,且必须在视图函数中接收
接收的数据类型都是字符串类型
(2)位置参数
如果需要获取url路径中的多个参数,那就添加多个括号,默认按照顺序匹配路径名字
创建子路由:
url(r'^testLocation/(\d{4})/(\d+)/(\d+)/',views.testLocation),
生成视图函数:
def testLocation(request,year,month,day):
print(year+'-'+month+'-'+day)
return HttpResponse('testLocation')
运行结果:
如果更换参数,会发生什么呢??
def testLocation(request,month,day,year):
print(year+'-'+month+'-'+day)
return HttpResponse('testLocation')
(3)关键字参数
为了防止上面情况的发生,我们可以使用关键字参数,不管位置怎么改变,都是根据变量名字来执行
创建子路由:
url(r'^testLocation/(\d{4})/(\d+)/(\d+)/',views.testLocation),
生成视图函数:
def testKey(request,month,day,year):
print(year + '/' + month + '/' + day)
return HttpResponse('testKey')
运行结果:
总结:
位置参数
eg:127.0.0.1:8000/vie/testRoute/1/2/3/
r(’^testRoute/(\d+)/(\d+)/(\d+)/’)
使用圆括号包含规则
一个圆括号代表一个参数
代表视图函数上的一个参数
参数个数和视图函数上的参数一一对应(除默认request)
关键字参数
可以在圆括号指定参数名字 (?Preg)
视图函数中存在和圆括号中name对应的参数
参数不区分顺序
个数也需要保持一致,一一对应
二.内置函数
内置函数
locals()
将局部变量,使用字典的形式打包
会将变量的名字设置为字典的key
将变量的值设置为字典的value
创建子路由:
url(r'^testLocal/',views.testLocal),
生成视图函数:
def testLocal(request):
name = '源一'
age = 18
return render(request, 'testLocal.html', context=locals())
创建并渲染模板:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
{{ name }} {{ age }}
</body>
</html>
运行结果:
三.反向解析(页面)
反向解析的用处:获取请求资源路径,避免硬编码。
下面主要是围绕如何在页面上使用反向解析,而如何在视图函数中使用反向解析的详情将在下一篇博文中说明
1.基本使用
(1)在根路由中设置namespace属性
url(r'^app/',include('App.urls',namespace='app')),
(2)在子路由中设置name属性
url(r'^index/',views.index,name='index'),
(3)reverse(‘app:index’)
在视图函数中的反向解析:
创建子路由:
url(r'^testReverse/',views.testReverse),
生成视图函数:
def testReverse(request):
a = reverse('app:index')
print(a)
return HttpResponse('测试反向解析')
运行结果:
在模板中的反向解析:
创建子路由:
url(r'^testUrl/',views.testUrl),
生成视图函数:
def testUrl(request):
return render(request,'testUrl.html')
创建模板:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
{#点击a标签 然后跳转到index请求#}
<a href="{% url 'app:index' %}">测试页面中的反向解析</a><br>
</body>
</html>
运行结果:
点击a标签前:
点击a标签后:
调用的时候,反向解析的路径不能有编译错误,格式是: {% url ‘namespace:name%}’
2.位置参数
创建子路由:
url(r'^testReverseLocation/(\d{4})/(\d+)/(\d+)/',views.testReverseLocation,name='testReverseLocation'),
生成视图函数:
def testReverseLocation(request, year, month, day):
print(year + '/' + month + '/' + day)
return HttpResponse('testReverseLocation')
在testUrl模板中添加:
<a href="{% url 'app:testReverseLocation' 2020 7 28 %}">反向解析之位置参数</a><br>
运行结果:
点击前:
点击后:
3.关键字参数
创建子路由:
url(r'^testReverseKey/(?P<year>\d{4})/(?P<month>\d+)/(?P<day>\d+)/',views.testReverseKey,name='testReverseKey')
生成视图函数:
def testReverseKey(request, month, day, year):
print(year + '/' + month + '/' + day)
return HttpResponse('testReverseKey')
在testUrl模板中添加:
<a href="{% url 'app:testReverseKey' year=2020 month=7 day=28 %}">反向解析之关键字参数</a>
运行结果:
点击前:
点击后:
如果在视图,模板中使用硬编码连接,在url配置发生改变时,需要变更的代码会非常多,这样导致我们的代码结构不是很容易维护,使用反向解析可以提高我们代码的扩展性和可维护性。