视图函数
- 第一个参数必须是request
- 返回值必须是
django.http.response.HttpResponseBase
的子类的对象
1 2 3 4
| from django.http import HttpResponse
def book(request): return HttpResponse('图书首页')
|
urls.py
settings.py
文件中配置了ROOT_URLCONF
为urls.py
,所以会在这个文件中寻找映射
路径和视图函数对应
1 2 3 4 5 6 7 8 9 10 11 12
| from django.contrib import admin from django.urls import path from book import views
urlpatterns = [ path('admin/', admin.site.urls), path('book/', views.book), path('book/detail/<book_id>/<category_id>/', views.book_detail), path('book/author/', views.author_detail), path('book/publisher/<int:publisher_id>/', views.publisher_detail), ]
|
url传递参数
urls.py
文件,<参数名>
传递,默认使用str
转换器,如<int:publisher_id>
。视图函数中,参数名要和它一致
- 查询字符串的方式,访问浏览器时参数如
?id=2
,http://127.0.0.1:8000/book/author/?id=2
- 转换器:
int
,path
,slug
,str
,uuid
1 2 3 4 5
| def author_detail(request): author_id = request.GET.get('id') text = '作者的id是:%s' % author_id return HttpResponse(text)
|
url映射时指定默认参数
views.py
中,可以给函数指定默认参数,url
中没有传递的话,使用默认参数
1 2
| def books(request, page=0): return HttpResponse(book_list[page])
|
url参数内置的转换器
- str:除了
/
以外的所有字符
- int:一个或多个数字
- path:所有字符
- uuid:只有满足
uuid.uuid4()
函数返回的字符串格式
- slug:
-
,_
,英文字母,数字任意组合
自定义url(path)转换器
- 定义一个类,直接继承自object就可以了
- 在类中定义一个属性regex,这个属性是用来保存url转换器规则的正则表达式
- 实现to_python(self, value)方法,作用是将url中的值转换一下,然后传给视图函数
- 实现to_url(self, value)方法,作用是在做url反转时,将传进来的参数转换后拼接成一个正确的url
- 将定义好的转换器,使用
django.urls.converters.register_converter
方法注册到django中
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
| from django.urls import converters, register_converter
class CategoryConverter(object): regex = r'\w+|(\w+\+\w+)+'
def to_python(self, value): result = value.split('+') return result
def to_url(self,value): if isinstance(value, list): result = '+'.join(value) return result else: raise RuntimeError('转换url时,分类参数必须为列表')
register_converter(CategoryConverter, 'cate')
|
注:可以将以上代码单独存为converters.py
文件,在__init__.py
中导入,from . import converters
,自动执行
urls模块化
- 主url对app的url引用,将url进行拼接,注意
/
,只写在末尾
1 2 3 4 5 6 7 8
| from django.contrib import admin from django.urls import path, include
urlpatterns = [ path('admin/', admin.site.urls), path('book/',include('book.urls')) ]
|
- app中的url单独放在自己的
urls.py
文件中,如下面名为的book
的app
1 2 3 4 5 6 7 8 9 10
| from django.urls import path from . import views
urlpatterns = [ path('', views.book), path('detail/<book_id>/', views.book_detail), path('list/',views.book_list), ]
|
url命名
url经常变换,取个名字,调用时用reverse('name')
进行反转,方便调用修改等
1 2 3 4 5 6 7
| from django.urls import path from . import views
urlpatterns = [ path('', views.index, name='index'), path('login/', views.login, name= 'login'), ]
|
应用(app)命名空间
多个app中,有可能出现同名的url,避免混淆,使用应用命名空间。
在app
的urls.py
中,定义一个叫app_name
的变量。
1 2 3 4 5 6 7 8 9
| from django.urls import path from . import views
app_name = 'front'
urlpatterns = [ path('', views.index, name='index'), path('login/', views.login, name= 'login'), ]
|
反转时使用应用命名空间:url名称
1
| login_url = reverse('front:login')
|
实例命名空间
一个app,可以创建多个实例,可以用多个url映射同一个app。为了避免在url反转时发生混淆,使用实例命名空间。
在项目根目录的urls.py
文件中,在include
函数中传递一个namespace
变量即可。
1 2 3 4 5 6
| urlpatterns = [ path('', include('front.urls')), path('cms1/', include('cms.urls',namespace='cms1')), path('cms2/', include('cms.urls',namespace='cms2')), ]
|
在url反转时,根据实例命名空间来指定具体的url。
1 2 3 4 5 6 7
| def index(request): username = request.GET.get('username') if username: return HttpResponse('CMS首页') else: current_namespace = request.resolver_match.namespace return redirect(reverse('%s:login'%current_namespace))
|
include函数
根目录urls.py
中,path()
中
include(module, namespace=None)
module
:子url的模块字符串
namespace
:实例命名空间,需先指定应用命名空间。即在子urls.py
中添加app_name
变量
path('cms1/', include('cms.urls',namespace='cms1'))
include((pattern_list, app_namespace), namespace=None)
元组(tuple)第一个参数是urls.py
模块字符串,第二个参数是应用命名空间。
应用命名空间,可以在子urls.py
中通过app_name
指定,也可以在include
函数中指定。
path('book/', include(('book.urls', 'book'), namespace='book'))
include(pattern_list)
pattern_list
是一个列表,元素为path
或re_path
1 2 3 4
| path('movie/', include([ path('', views.movie), path('list/', views.movie_list), ]))
|
re_path
- 推荐使用原生字符串,即
r
开头的字符串
- 定义的变量,需要用
()
括起来,?P<参数的名字>
,后面添加正则表达式规则
- 优先用
path
1 2 3 4 5 6 7 8 9
| from django.urls import re_path from . import views
urlpatterns = [ re_path('^$', views.article), re_path(r'^list/(?P<year>\d{4})/$', views.article_list), re_path(r'^list/(?P<month>\d{2})/$', views.article_list_month), ]
|
reverse()
- 反转url时,如果需要添加参数,使用
kwargs
参数传递
1 2 3
| from django.shortcuts import redirect, reverse
detail_url = reverse('detail', kwargs={'article_id':1, 'page':2})
|
- 如果添加查询字符串的参数,必须手动进行拼接
1
| login_url = reverse('login') + '?next=/'
|