Django视图
在Django初识体验中,我将视图和路由配置都写在了一个urls文件中,这只是Django的初体验为了方便才这样写的。事实上,Django的视图一般写在每个app的views.py中;但如果将配置都写在配置文件夹(与项目同名的文件夹,下面统一描述为配置文件夹)中的urls中。无疑不方便我们管理每个app(模块)的视图。因此,我们需要在每个app中新建一个urls文件夹。
include函数
上面我们说到我们需要在每一个app中创建一个urls文件,但我们的路由配置都在配置文件夹的urls中(即我们访问路由时,只能够访问该文件配置好的路由),如何让Django能够匹配到我们在每个app中的urls文件写好的路由匹配规则,就需要用到Django自带的include函数。
include里面的参数为每个app的urls文件,将这配置在配置文件夹的urls文件中。
path('book/', include('book.urls'))
redirect(重定向)
重定向简单说一下就是在访问一个url时,自动跳转到另一个url。
实现方式也很简单:
redirect('/your_route')
这样存在一个问题就是把路由写死了,如果路由需要改的话,那么重定向这里也要改。小项目还好,如果项目大了,要想找起来就会特别麻烦。所以我们给这个路由器起个名字name,让name绑定这个路由,redirect后面直接跟这个名字,即可通过这名字找到对应的路由。实现方法也很简单:
- 在该app的urls中的path加个name参数,如下。
path('your_route/', views.route_func, name='route_name')
- 然后在views.py中更改redirect
redirect('route_name')
应用命名空间
在上面所说的对路由的命名也存在一个问题,如果我们在两个app中都写了登录路由,也同时命名为login,那么这两个就会产生冲突,如何避免冲突则需要使用应用命名空间。
应用命名空间的作用就是将每个app都设置一个名称,让其与其他app隔绝开来。实现方法很简单,只需要在每个app的urls将如下的配置项
# 注意app_name是固定写法,不能更改
app_name = 'your_app_name'
更改redirect
# app_name:route_name, 表示该路由名称是在app_name下的,这样就不会与其他app产生冲突
redirect('your_route_name:route_name')
注意:如果一个app配置了应用命名空间,最好将其它的app也命名
实例命名空间
实例命名空间作为一个拓展来说,,如果说应用命名空间是整个项目的其中一个分支(app),那么实例命名空间就是app下的分支,它的作用是将不同的路由都指向同一个app。配置也很简单。只需要在include中添加一个namespace参数
- 在配置文件的url作如下配置
path('hello_user/', include('hello.urls', namespace='hello_user'))
path('hello_admin/', include('hello.urls', namespace='hello_admin'))
- 打印namespace(在视图函数下打印)
current_namespace = request.resolver_match.namespace
print('current_namespace')
访问hello_user/,会打印hello_user;访问hello_admin,会打印hello_admin
应用命名空间是区别不同的app,而实例命名空间是区别同一个app下不同的实例
url反转传递参数
当我们重定向的路由需要传递参数,我们就需要reverse函数
- 需要附加数据的url
redirect(reverse('app_name:route_name') + '?name=xxx')
- 需要传递参数的url
redirect(reverse('app_name:route_name', kwargs={'name': 'xxx'}))
Django内置转换器
Django内置的转换器如下:想详细了解可参考https://blog.csdn.net/weixin_41712808/article/details/83116611.
使用:
# int限制了只能输入整数类型
path('search/<int:search_name>', view.film_search, name='search')
re_path
当我们需要对路由传递的参数有限制的时候,可以用re_path,它的参数和path相似,不过第一个参数可以是一个正则表达式
re_path(r'search_year/(?P<film_year>(19|20)\d{2})/(?P<film_month>(0|1)\d{1})',
views.search_film_date, name='search_year'