django之URL

本文详细介绍了Django的URL配置,包括基本格式、正则表达式详解、分组匹配、命名和反向解析、命名空间模式以及URL的删除操作。通过正则表达式和视图函数结合,实现路径分发,并讲解了URL命名、反向解析的两种传参方式及其应用场景。
摘要由CSDN通过智能技术生成

路由系统,进行路径分发.
官方文档:(https://docs.djangoproject.com/en/1.11/topics/http/urls/)
一.基本格式:
1.1版本
urlpatterts = [
url(正则表达式,views视图,参数,别名)
]
1.正则表达式:一个正则表达式字符串
2.views视图:一个可调用对象,通常为一个视图函数
3.参数:可选的要传递给视图函数的默认参数(字典形式)
4.别名:一个可选的name参数

eg:
from django.conf.urls import url
from . import views
urlpatterns = [
url(r'^articles/2003/$', views.special_case_2003), 
	url(r'^articles/([0-9]{4})/$', views.year_archive), #年份
	url(r'^articles/([0-9]{4})/([0-9]{2})/$', views.month_archive), #年月
	url(r'^articles/([0-9]{4})/([0-9]{2})/([0-9]+)/$', views.article_detail), #年月日
	]

2.0版本

eg:
from django.urls import path,re_path
	urlpatterns = [
	path('articles/2003/', views.special_case_2003),
	path('articles/<int:year>/', views.year_archive),
	path('articles/<int:year>/<int:month>/', views.month_archive),
	path('articles/<int:year>/<int:month>/<slug:slug>/', views.article_detail),
	]

二.正则表达式详解

	^  #以什么开头
	$  #以什么结尾
	[] #里的内容任意一个都可以 
	{} #个数
	?  #0个或1个
	+  #1个或多个
	*  #个或多个
	.  #除了换行符之外的任意字符
	\d #数字 
	\w #字母和数字

注意事项:
1.urlpatterts中的元素.按照书写顺序从上往下逐一匹配正则表达式,一旦匹配成功,则不再继续匹配,需要写的严谨,加上^ $
2.若要从url中捕获一个值,只需要在它周围放置()(正则表达式的机制)
3.路径前不需要加/ eg::应该是^articles 而不是 ^/articles。
4.每个正则表达式前面的’r’是可写可不写,但是建议写上
5.网址结尾’/‘可手动加也可以不写,django会自动补全
原因:
Django中 默认这个参数为 APPEND_SLASH = True。 # 其作用就是当url访问地址后面不加/,时,django自动在网址结尾加’/’,从而不影响网址的正常使用
需要注意的是:Django settings.py配置文件中默认没有 APPEND_SLASH 这个参数.

#当我们访问网址,输入http://www.example.com/blog 时,默认将网址自动转换为 http://www.example/com/blog/
#但是如果在settings.py中设置了 APPEND_SLASH=False,
	此时我们请求 http://www.example.com/blog 时就会提示找不到页面。
	原因是: APPEND_SLASH=False    django就不会补全网址,也就是浏览器不会返回要请求的页面.
eg:
		from django.conf.urls import url
		from app01 import views
		urlpatterns = [
			url(r'^blog/$', views.blog),
		]

三.分组匹配
1.分组命名正则表达式组的语法:
(?Ppattern) #name是组的名称,pattern是要匹配的模式。 注意P大写

eg:
	1.(?P<month>[0-9]{2}) #分组别名为month 0到9任意取2个数字
	2.(?P<day>[0-9]{2})   #分组别名为day 0到9任意取2个数字
	3.(?P<year>[0-9]{4})  # 分组别名为year 0到9任意取4个数字
	4.
	from django.conf.urls import url
	from . import views
	urlpatterns = [
		url(r'^articles/2003/$', views.special_case_2003),
		#以下三个对上面的一个路由做了一个分组命名匹配
		url(r'^articles/(?P<year>[0-9]{4})/$', views.year_archive),#年份
		url(r'^articles/(?P<year>[0-9]{4})/(?P<month>[0-9]{2})/$', views.month_archive), #年月
		url(r'^articles/(?P<year>[0-9]{4})/(?P<month>[0-9]{2})/(?P<day>[0-9]{2})/$', views.article_detail),#年月日
	]
2.无论使用什么样的正则表达式,获取到的参数永远都是字符串
	#每个在URLconf中捕获的参数都作为一个普通的Python**字符串**传递给视图,无论正则表达式使用的是什么匹配方式。			
	eg:
	url(r'^articles/(?P<year>[0-9]{4})/$', views.year_archive),
	 # 传递到视图函数中的year_archive() 中的year参数永远是一个**字符串类型**。

3.视图函数中的指定默认值
多个地址,可以匹配同一个视图函数

eg:
	# urls.py中
		from django.conf.urls import url
		from . import views
		urlpatterns = [
			url(r'^blog/$', views.page), #不会额外传参
			url(r'^blog/page(?P<num>[0-9]+)/$', views.page),]  #会额外传一个关键字参数
			
	#views.py中(可以为num指定默认值)
		def page(request, num="1"):   
			#如果urls中未传参,使用num=1这个默认参数,如果urls传参,则使用urls传过来的参数
			pass

在上面的例子中,两个URL模式指向相同的view - views.page -
如果第一个模式匹配上了,page()函数将使用其默认参数num=“1”,
如果第二个模式匹配上,获取url上通过正则表达式获取到的num值,
并且以关键字参数的形式传递给page()的形参num。
4.include
作用:进行一个分类
一般不进行修改settings中的ROOT_URLCINF的值,主要是用include
url与视图的对应关系写在哪里没有关系,重点是django项目的settings中的ROOT_URLCINF的值,
ROOT_URLCINF的值:表示的是从哪一个app项目中去找该django项目的url与视图的对应关系(即urls)
一般放到目录分级的应用中

eg:
from django.conf.urls import url,include
urlpatterns = [
	url(r'^admin/', admin.site.urls),
	url(r'^blog/', include('blog.urls')), 
	 # 只有用上'blog/'和blog里的urls中的'路径'才可以找到对应的视图函数,才能获取到相应的页面 
							#可以包含其他的URLconfs文件

四.url的命名和反向解析
4.1.传参方式一:位置传参(定义的时候,使用分组)
步骤:
第一步:定义,给url起一个别名(在urls中)
在url中,最后加上一个name=‘别名’
url(正则表达式,views视图,参数,name=‘别名’)

eg:
from django.conf.urls import url
	from . import views

	urlpatterns = [
		# ...
		url(r'^articles/([0-9]{4})/$', views.year_archive, name='news-year-archive'), 
		 #位置参数传参
		# ...]

4.1.2.第二步:使用,进行反向解析(两种方式:1在模板中,2在视图函数中)
1.解析方式一:在模板中进行反向解析(可以通过一个html页面.跳转到起别名的html页面)
{% url ‘别名’ ‘参数’%} #参数之间以空格分割 参数如果是以arg就是位置传参.但是kwargs就是关键字传参
#获取到的结果是一个完整的路径(取别名的的那个url里的路径),数据类型是字符串

eg:
	<a href="{% url 'news-year-archive' '2012' %}">2012 Archive</a>  
	#参数是反向解析的时候定义,位置传参
	<ul>
	
	{% for yearvar in year_list %}
	<li><a href="{% url 'news-year-archive' yearvar %}">{{ yearvar }} Archive</a></li>  
	 #参数是反向解析的时候定义 位置传参
	{% endfor %}
	</ul>

2.解析方式二:在视图函数中进行反向解析
1.引用reverse
from django.urls import reverse
2.使用reverse函数
reverse(‘别名’,args=(参数,)) #注意参数要以元祖的形式,参数是反向解析的时候进行定义, 参数如果是以arg就是位置传参.但是kwargs就是关键字传参
#reverse函数获取到的结果是一个完整的路径(取别名的的那个url里的路径),数据类型是字符串

eg:
	from django.urls import reverse
	from django.shortcuts import redirect

	def redirect_to_year(request):
		# ...
		year = 2006
		# ...
		return redirect(reverse('news-year-archive', args=(year,)))  
		 #获取到完整的路径,直接进行跳转:http/127.0.0.1:8000/articles/([0-9]{4})/
										#参数是一个元祖,但是参数是反向解析的时候进行定义

4.2.传参方式二:关键字传参(定义的时候,使用了命名分组,命名分组传参可以用位置参数,需要一一对应)
步骤:
4.2.1.第一步:定义,给url起一个别名(在urls中)
在url中,最后加上一个name=‘别名’
url(正则表达式,views视图,参数,name=‘别名’)

	eg:
		from django.conf.urls import url
		from . import views

		urlpatterns = [
			# ...
			url(r'^articles/?P<year>([0-9]{4})/$', views.year_archive, name='news-year-archive'), #命名分组 关键字传参
			# ...]

4.2.2.第二步:使用,进行反向解析(两种方式:1在模板中,2在视图函数中)
1.解析方式一:在模板中进行反向解析(可以通过一个html页面.跳转到起别名的html页面)
{% url ‘别名’ ‘参数’%} #参数之间以空格分割 参数如果是以arg就是位置传参.但是kwargs就是关键字传参

eg:
	<a href="{% url 'news-year-archive' year='2012' %}">2012 Archive</a> 
	 #参数是反向解析的时候定义,关键字传参
	<ul>
	
	{% for yearvar in year_list %}
	<li><a href="{% url 'news-year-archive' year=yearvar %}">{{ yearvar }} Archive</a></li>   
	#参数是反向解析的时候定义  关键字传参
	{% endfor %}
	</ul>

2.解析方式二:在视图函数中进行反向解析
1.引用reverse
from django.urls import reverse
2.使用reverse函数
reverse(‘别名’,kwargs={key:value}) #注意参数要以元祖的形式,参数是反向解析的时候进行定义, 参数如果是以kwargs就是关键字传参
#reverse函数获取到的结果是一个完整的路径(取别名的的那个url里的路径),数据类型是字符串

eg:
	from django.urls import reverse
	from django.shortcuts import redirect

	def redirect_to_year(request):
		# ...
		year = 2006
		# ...
		return redirect(reverse('news-year-archive', kwargs={'year':year}))
		 #获取到完整的路径,直接进行跳转:http/127.0.0.1:8000/articles/([0-9]{4})/
										#参数是一个字典,参数是反向解析的时候进行定义

五…命名空间模式
名称空间指的是将名称空间进行隔离,当有两个重名的url时,后执行的url的内容会覆盖先执行的url的内容
1.定义
定义语法:namespace=‘名称’

		urls中
		from django.conf.urls import url, include
		urlpatterns = [
		url(r'^app01/', include('app01.urls', namespace='app01')),  #进行命名空间定义
		url(r'^app02/', include('app02.urls', namespace='app02')),
		
		app01中的urls.py
		from django.conf.urls import url
		from app01 import views
		app_name = 'app01'
		urlpatterns = [
			url(r'^(?P<pk>\d+)/$', views.detail, name='detail')
			]
		
		app02中的urls.py
		from django.conf.urls import url
		from app02 import views
		app_name = 'app02'
		urlpatterns = [
			url(r'^(?P<pk>\d+)/$', views.detail, name='detail')
			]
	
	现在,我的两个app中 url名称重复了,我反转URL的时候就可以通过命名空间的名称得到我当前的URL。

	使用语法:
	'命名空间名称:名称'

2.使用
1.方法一:模板中使用:

		{% url 'app01:detail' pk=12 %}
		{% url 'app02:detail' pk=22 %}

2.方法二:views中的函数中使用

		v = reverse('app01:detail', kwargs={'pk':11})
		v = reverse('app02:detail', kwargs={'pk':11})
		 这样即使app中URL的命名相同,我也可以反转得到正确的URL了。 

六…删除三合一
步骤:
1.在urls中,定义删除的对应关系

urlpatterns = [
url(r'^admin/', admin.site.urls),
	url(r'^show/$', views.show, name='show'),
	url(r'^show_books/', views.show_book, name='show_books'),
	url(r'^show_authors/', views.show_author, name='show_authors'),
	url(r'^show_publisher/', views.show_publisher, name='show_publisher'),
	url(r'delete_(publisher|books|authors)/(\d+)/', views.delete, name='delete'),]  
		#删除三和一的对应关系

2.在展示页面中确定要删除的pk

show_books.html页面中
	<td><a href="{% url 'delete' 'books' books_obj.pk %}">删除</a></td>
show_authors.html页面中
	<td><a href="{% url 'delete' 'authors' author_obj.pk %}?page=01">删除</a></td>
show_publisher.html页面中
	<td><a href="{% url 'delete' 'publisher' publisher_obj.pk %}?page=02">删除</a></td>

3.在views中写上函数逻辑

  #参数是从html页面中传来,object代表的是删除的哪一个
	def delete(request, object, pk):
		#获取到表对象(通过反射 )  object.capitalize()找到对应的表,从而可以获取要删除的对象
		object_class = getattr(models, object.capitalize())
		#获取要删除的对象,并且删除
		object_class.objects.filter(pk=pk).delete()
		#重定向,到展示页面
		return redirect(reverse('show_{}'.format(object)))
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值