目录
一、视图函数
视图函数:
1.第一个函数的参数必须是request
2.视图函数的返回值必须是HTTPResponseBase的及其子类
二、URL传参
方法1.在url中使用参数
首先需要在视图函数的参数中写明要传递的参数,比如在play应用中的views.py写一个playing函数,需要传递歌曲id和种类id
def playing(request,song_id,category_id):
text = "您播放的歌曲id是:%s ,歌曲种类id:%s" % (song_id,category_id)
return HttpResponse(text)
然后在项目firstproject里的urls.py中写一个url,paly是应用名,playing是函数名,然后将视图函数的参数复制到<>里边
path('play/playing/<song_id>/<category_id>/', views.playing),
在访问时,需要按照 定义的url的格式传入参数,如果有参数个数不对等问题,都会出不来结果
方法2.查询字符串方式使url传参
如下图,大多数查询都使用这种查询字符串的方式,?后边即为查询的内容,
此种方法不需要在视图函数中逐一匹配参数,只需写明GET请求传递的参数,下面的id即是查询时?id=“查询的内容”
def singer_detail(request):
singer_id = request.GET.get('id')
text = '歌手的id是:%s' % singer_id
return HttpResponse(text)
在项目的urls里,定义的play即为应用play的名称,singer_id即为查询之前匹配的字符,也可以改成别的,比如singer,只要在访问的时候和这个定义的url一致就可以
path('play/singer_id/', views.singer_detail),
三、URL参数转换器
- str:除了'/'之外都可以
- int:只有一个或多个阿拉伯数字才可以
- path:所有字符都可以
- UUID:只有满足'uuid.uuid4()'这个函数返回的 字符串才满足
- slug:英文中的-或者英文字符、阿拉伯数字或者下划线才满足
比如限制歌曲id为阿拉伯数字,种类id是字符
path('play/playing/<int:song_id>/<str:category_id>/', views.playing),
如果song_id不是阿拉伯数字,就会报错
四、URL分层模块化
当页面太多,有太多个关于不同内容的url在项目firstproject中的url定义时就会容易太乱,可以根据不同的内容,比如所有关于播放play这个模块的url可以放在应用play的urls.py里,模块化操作如下:
步骤1. 在应用play中新建urls.py,写入如下代码:不同于项目中的urls.py里的定义,在此处定义的url默认是从play开始path('',views.play),是指path('play',views.play)。其他的没有区别
from django.urls import path
from . import views
urlpatterns = [
path('', views.play),
# path('play/playing/<int:song_id>/<str:category_id>/', views.playing),
path('playing/<int:song_id>/<str:category_id>/', views.playing),
path('singer/', views.singer_detail),
]
步骤2:而在项目的urls.py中,导入include的引用,然后在url定义中前半部分是应用play的url中省下的部分,后半部分加入include(),include里边是导入的应用play里的urls,这里是项目的urls和play的urls进行了拼接
from django.urls import path,include
from play import views
from django.http import HttpResponse
urlpatterns = [
path('admin/', admin.site.urls),
path('play/', include('play.urls')),
]
五、URL的命名
1.为什么要命名?
比如在做跳转时,会经常修改url,而此时已经有多处都用到url,所以如果给url一个命名,在views.py文件中使用的是url的命名,只需要翻转一下,就可以找到在urls.py中定义的原来的url,如果想要修改url,也只需要去urls.py中修改一处即可
2.如何命名?
比如在user的urls.py中,只需在path中加一个name参数
from django.urls import path
from . import views
urlpatterns = [
path('', views.index, name='index'),
path('login/', views.login, name='signin'),
]
在views.py中的视图函数使用时,可以将url的命名用reversed反转一下,然后代替原来的url写入跳转函数中,如下:
from django.http import HttpResponse
from django.shortcuts import redirect
def index(request):
username = request.GET.get('username')
if username:
return HttpResponse("用户中心")
else:
login_url = reversed('signin')
return redirect(login_url)
#return redirect('/user/login/')
def login(request):
return HttpResponse("登录页面")
六、应用命名空间、实例命名空间
- 为什么要用应用命名空间?
在做反转时,reverse('urlname')会根据拥有此url名字的url进行解析,但是如果多个应用有相同的url名称,那么可能出来的是别的应用的页面,所以应用命名空间,app_name是应用命名空间的参数,比如user的urls.py中代码如下:
from django.urls import path
from . import views
#应用命名空间的变量叫做app_name
app_name = 'user'
urlpatterns = [
path('', views.index, name='index'),
path('login/', views.login, name='signin'),
]
- 为什么要用实例命名空间呢?
同一个app可以使用不同的url进行映射,即同一个app下可以有多个实例,而用应用命名空间做反转的时候,就会发生混淆,所以实例名命名空间>应用命名空间,而且必须有应用命名空间,才能使用实例命名空间。代码如下:
在项目的urls.py里,namespace为实例名命的参数
path('user1/', include('user.urls', namespace='user1')),
path('user2/', include('user.urls', namespace='user2')),
在应用user的urls.py里的视图函数中利用request.resolver_match.namespace 获取实例命名空间
current_namespace = request.resolver_match.namespace
return redirect(reversed("%s:login"%current_namespace))