Python Django: urlpatterns 变量的语法
urlpatterns 变量的语法
1 包含其它的URLconfs
在实际项目中,将所有应用的URL路径放置于一个 urls.py ,容易发生因为耦合程度高,造成后期自定义配置困难、维护成本高等问题。由此,Django 的 urls.py 配置文件可以 “include” 其它URLconf 模块,将一部分URL 放置于其它URL 下面。
1.1 项目目录结构如下
注:记得在settings.py中配置新添加的应用;
1.2 不同目录下的urls.py配置
-
djangoProject\djangoProject\urls.py
from django.conf.urls import url, include from django01 import views urlpatterns = [ url(r'^$', views.home), url(r'django01/', include('django01.urls')), url(r'django02/', include('django02.urls')), ]
-
djangoProject\django01(/02)\urls.py
from django.conf.urls import url from django01(/02) import views urlpatterns = [ url(r'^index/', views.index), ]
-
其他配置与之前一致。
2 url别名反向解析
# urls.py 下配置 url 别名 name
urlpatterns = [
url(r'^books/', views.books, name='books'),
url(r'^booksadd/', views.books_add, name='books_add'),
url(r'^booksedit/(\d)+', views.books_edit, name='books_edit'),
url(r'^booksdelete/(\d)+', views.books_delete, name='books_delete'),
]
# views.py: 利用别名配置反向解析
from django.urls import reverse
# 编辑内容时,可能利用原始数据的内容,通过 url 定位所点击数据对象,再通过数据对象进行后序操作
def books_edit(request, book_id):
if request.method == 'GET':
try:
book_obj = Books.objects.get(id=book_id)
print(reverse('books_edit')) #/booksedit/ 无参数
print(reverse('books_edit',args=(2,))) #/booksedit/2/ 带参数
except Exception:
return HttpResponse('错误的修改!')
return render(request, 'booksedit.html', {'book_obj': book_obj, 'book_id': book_id})
else:
status = True if (request.POST.get('status') == 'on') else False
title = request.POST.get('title')
price = request.POST.get('price')
date = request.POST.get('date')
publisher = request.POST.get('publisher')
Books.objects.create(**{
'status': status,
'title': title,
'price': price,
'date': date,
'publisher': publisher,
})
return redirect(reverse('books'))
# book_edit.html: form 表单用于接收 url 中的参数。
<form action="{% url 'books_edit' %}" method="post"> # 无参数
<form action="{% url 'books_edit' book_id %}" method="post"> # 有参数
3 url 命名空间
3.1 命名解析冲突实验环境
在 django 项目中创建两个应用 app01、app02 。
-
配置项目的 urls.py 如下:
from django.contrib import admin from django.urls import path, include urlpatterns = [ path('admin/', admin.site.urls), path('app01/', include('app01.urls')), path('app02/', include('app02.urls')), ]
-
在 app01、app02 文件下创建 urls.py 、views.py 分别配置如下:
************ app01/urls.py ************ from app01 import views from django.urls import re_path urlpatterns = [ re_path(r'index/', views.index, name='index'), ] ************ app01/views.py ************ from django.shortcuts import reverse,HttpResponse # Create your views here. def index(request): print('app01: ', reverse('index')) return HttpResponse('app01 index') ************ app02/urls.py ************ from app02 import views from django.urls import re_path urlpatterns = [ re_path(r'index/', views.index, name='index'), ] ************ app02/views.py ************ from django.shortcuts import reverse, HttpResponse # Create your views here. def index(request): print('app02: ', reverse('index')) return HttpResponse('app02 index')
-
通过浏览器分别访问
127.0.0.1:8000/app01/index
与127.0.0.1:8000/app02/index
,虽然前端显示正确,但查看后台输出:app01: /app02/index/ app02: /app02/index/
可以发现,app01 反向解析的
‘index’
为/app02/index/
。命名解析发生冲突。
3.2 解决方式:命名空间
3.2.1 方式一
在项目urls.py文件下,将 include() 所包含的模块中设置一个由 应用urlpattern
与 应用名称
组成的二元组。
-
修改项目的 urls.py 如下:
from django.contrib import admin from django.urls import path, include urlpatterns = [ path('admin/', admin.site.urls), path('app01/', include(('app01.urls', 'app01'), namespace='app01')), path('app02/', include(('app02.urls', 'app02'), namespace='app02')), ]
-
在 app01、app02 文件下修改 views.py 配置如下:
************ app01/views.py ************ from django.shortcuts import reverse,HttpResponse # Create your views here. def index(request): print('app01: ', reverse('app01:index')) return HttpResponse('app01 index') ************ app02/views.py ************ from django.shortcuts import reverse, HttpResponse # Create your views here. def index(request): print('app02: ', reverse('app02:index')) return HttpResponse('app02 index')
-
通过浏览器分别访问
127.0.0.1:8000/app01/index
与127.0.0.1:8000/app02/index
,前端显示正确,查看后台输出正常解析:app01: /app01/index/ app02: /app02/index/
3.2.2 方式二
在 include 模块中,指定 app_name 。
-
在 app01、app02 文件下修改 urls.py 分别配置如下:
************ app01/urls.py ************ from app01 import views from django.urls import re_path # 添加 app_name。 app_name = 'app01' urlpatterns = [ re_path(r'index/', views.index, name='index'), ] ************ app01/views.py ************ from django.shortcuts import reverse,HttpResponse # Create your views here. def index(request): print('app01: ', reverse('app01:index')) return HttpResponse('app01 index') ************ app02/urls.py ************ from app02 import views from django.urls import re_path # 添加 app_name 。 app_name = 'app02' urlpatterns = [ re_path(r'index/', views.index, name='index'), ] ************ app02/views.py ************ from django.shortcuts import reverse, HttpResponse # Create your views here. def index(request): print('app02: ', reverse('app02:index')) return HttpResponse('app02 index')
-
通过浏览器分别访问
127.0.0.1:8000/app01/index
与127.0.0.1:8000/app02/index
,前端显示正确,查看后台输出正常解析:app01: /app01/index/ app02: /app02/index/