Django(4) 路由层

路由层

路由匹配

1、路由就是ip和port后面的地址
2、url()方法
3、urlpatterns = [
	url(r'^admin/', admin.site.urls),
] 第一个参数其实是一个正则表达式,一旦第一个参数匹配到了内容直接结束匹配,执行对应的视图函数

路由层之APPEND_SLASH

urlpatterns = [
	url(r'^test/$', views.test),
] APPEND_SALSH默认值是True,就是加入你没有添加斜线,会自动帮你添加上。也就是,它请求了两次。

无名分组

--> 回顾 正则分组就是括号括起来

urls.py 路由层 
  url(r'test(\d+)/$', views.test1),
views.py视图层
def test1(request,xx):
	print(xx)
	return HttpResponse('aa')

image

最终路由层得到的结果是:
123
总结:无名分组就是将括号内正则表达式匹配的内容,当作位置参数传递给函数,所以要给视图的函数,加一个形参。

有名分组

urls.py 路由层 
   url(r'test(?P<id>\d+)/$', views.test1),
views.py视图层def test1(request,id):
print(id)
return HttpResponse('aa')

image

最终路由层得到的结果是:
123
总结:有名名分组就是将括号内正则表达式匹配的内容,当作关键字参数传递给函数,所以要给视图的函数,加一个参数名为id就是有名分组的组名。

结合使用

有名分组和无名分组是不可以将混合使用的
相同的组是可以多个使用的

反向解析

当路由频繁变化的时候,html界面上的地址需要做到动态解析

(1)路由层:
url(r'test1/', views.test1),
url(r'test2/', views.test2),

(2)视图层:
def test1(request):
	return HttpResponse('judyjudyjudy')

def test2(request):
	return render(request,'test2.html')

(3)模版层
<a href="/test1/">111</a>
注意:href既可以写完整的网址,也可以写路由

准备好环境之后,当我们开启项目,输入test2路由的时候,看到的页面就是111的链接,由于在后端已经写好会向test1发get请求,但是此时如果路由层的test1这个url需要改变的话,在页面上点111就找不到原本的页面了,所以第一个方法就是在模版层改一下,但是如果有很多很多呢,手动改不现实了,所以此时无名就需要动态解析了。

反向解析方法

1、给路由和视图函数对应关系添加一个别名,
url(r'test1/', views.test1,name='test1_name'),
2、根据别名动态解析出一个结果,该结果可以直接访问对应的路由
在前端的使用
<a href="{% url  'test1_name' %}">111</a>
在后端的使用
(1)导模块reverse
(2)(reverse('test1_name')) 就可以拿到变更过的url
(3)return redirect('test1_name')-->注意:redirect后面可以直接跟url和视图函数关系的别名

无名有名反向解析

准备案例
路由层
  url(r'test(\d+)/$', views.test1, name='test1_name'),
视图层
def test1(request,xx):
	print(reverse('test1_name'))
	return HttpResponse('judyjudyjudy')

image

正确写法

🌼后端
视图层
print(reverse('test1_name',args=(123,)))-->在反向解析里加上一个args=,在后期的生产环境中,无名通常放主键值
🌼前端
<a href = '{%url 'index_name' 1 %}'></a>
注意:无名有名的用法是一样

路由分发

Django中的每一个应用都有自己的urls.py,static文件夹,templates文件夹,基于上述特点,使用Django左分组开发十分方便,每个人只需要写自己的应用即可

案例:
1、先创建2个app django-admin startapp app01
2、分别子啊app01和app02中创建urls.py和templates文件夹
拿app01举例子,在app01的urls.py写路由,注意需要导入该导入的
from django.conf.urls.urls import url
from app01 import views
 urlpatterns = [
			url(r'^index/',views.index),
			]
3、再在主路由层分发路由
from django.conf.urls import url,include
from django.contrib import admin
urlpatterns = [
	url(r'^admin/', admin.site.urls),
	url(r'^app01/', include('app01.urls')),
	url(r'^app02/', include('app02.urls')),

名称空间

当不同app里面的urls.py取的别名一样的时候,就可以使用名称空间的概念

🌹以下是app02的
from django.conf.urls import url
from app02 import views

urlpatterns = [
	url(r'^index/',views.index,name='index_name'),-->这里的名字一样了
]
🌹以下是app01的
from django.conf.urls import url
from app01 import views

urlpatterns = [
	url(r'^index/',views.index,name='index_name'),-->-->这里的名字一样了
]

2、后端
此时我们可以在总urls.py中加上名称空间:
urlpatterns = [
	url(r'^admin/', admin.site.urls),
	url(r'^app01/', include('app01.urls',namespace='app01')),
	url(r'^app02/', include('app02.urls',namespace='app02')),
]
-->然后在view.py中
def index(request):
	print(reverse('app02:index_name')) <-- 更改这个就可以了
	return HttpResponse('这是app02')
3、前端
在html中 
<a href='{%url 'app01:index_name' %}'></a>

4、当然也有解决方式2,别名不要冲突(加上自己的应用名前缀,这样是一定不会冲突的)

上传文件

form表单上传文件注意事项
1、method必须是post
2、enctype改成form-data
3、前端
<form action="" method="post" enctype="multipart/form-data">
<input type="file" name="myfile"> <br>
<input type="submit">
4、后端
def func3(request):
	if request.method == 'POST':
		print(request.FILES) # <MultiValueDict: {'myfile': [<InMemoryUploadedFile: 书库库 多表查询.md (application/octet-stream)>]}>
		file_obj = request.FILES.get('myfile')  # -->自己在前端设定的名字是什么就是什么
		print(type(file_obj)) # <class 'django.core.files.uploadedfile.InMemoryUploadedFile'>
		print(file_obj.name)
		print(type(file_obj.name)) # <class 'str'>
		with open(r'%s' % file_obj.name, 'wb') as f:  # -->因为要写入所以使用w模式,看文件,如果文件是文本模式那么wt模式就可以了,如果是其他文件格式,那么用b模式
			for i in file_obj:  # 这个文件对象是支持for循环的
				# 这句for循环官方推荐使用:
				# for chunks in file_obj.chunks():
				# f.write(chunks)
				f.write(i)
	return render(request, 'file.html')

FBV和FCV

FBV是基于函数的视图
FCV是基于类的视图

🌼基本使用
1、在视图层先导入模块
from django.views import View
2、写一个类
class MyView(View):
def get(self,request):
return HttpResponse('get方法')
def post(self,request):
return HttpResponse('post方法')
3、在路由层
url(r'^func1',views.MyView.as_view())  # 这句话等价于url(r'func4',views.view)
posted @ 2022-02-23 18:24  JudyJU  阅读(109)  评论(0)    收藏  举报