本文共 3375 字,大约阅读时间需要 11 分钟。
在前面的例子里面,我们已经了解,Django里面可以通过在Project同名的那个目录下的urls.py文件里面配置路由,根据用户输入的url,调用不同的函数或者类的方法。下面看看具体的一些例子。
单一的路由对应关系。这种方式最直接,前面已经多次出现, 可以是fbv或者cbv类型的。
1 2 | url(r '^login/' , views.login) url(r '^home/' , views.Home.as_view()), |
基于正则表达式的路由关系。具体来说,也可以分成两种:a. url(r'^detail-(\d+).html', views.detail) , 这里出现了一个分组(\d+),因此需要额外的再传递一个参数给detail这个函数,如果多个分组的话,需要按照顺序传递多个参数到detail函数b. url(r'^detail-(?P<nid>\d+)-(?P<uid>\d+).html', views.detail), 这里因为指定了nid和uid,因此传递参数的时候也需要指明具体是传递给谁的。c. 上面两种情况都可以通过万能参数实现 def detail(request, *args,**kwargs)
实战模板:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | url(r '^detail-(\d+)-(\d+).html' , views.detail), def func(request, nid, uid): pass def func(request, * args): args = ( 2 , 9 ) def func(request, * args, * * kwargs): args = ( 2 , 9 ) #-----------------------------我是分割线------------------------------------ url(r '^detail-(?P<nid>\d+)-(?P<uid>\d+).html' , views.detail) def func(request, nid, uid): pass def funct(request, * * kwargs): kwargs = { 'nid' : 1 , 'uid' : 3 } def func(request, * args, * * kwargs): args = ( 2 , 9 ) |
给路由的映射设置名称,这样更方便调用。reverse方法可以通过name倒过来找url的路径
url.py
1 2 3 | url(r '^asdfasdfasdf/' , views.index, name = 'i1' ), url(r '^yug/(\d+)/(\d+)/' , views.index, name = 'i2' ), url(r '^buy/(?P<pid>\d+)/(?P<nid>\d+)/' , views.index, name = 'i3' ), |
view.py
1 2 3 4 5 | def func(request, * args, * * kwargs): from django.urls import reverse url1 = reverse( 'i1' ) # asdfasdfasdf/ url2 = reverse( 'i2' , args = ( 1 , 2 ,)) # yug/1/2/ url3 = reverse( 'i3' , kwargs = { 'pid' : 1 , "nid" : 9 }) # buy/1/9/ |
xxx.html
1 2 3 | {% url "i1" %} # asdfasdfasdf/ {% url "i2" 1 2 %} # yug/1/2/ {% url "i3" pid=1 nid=9 %} # buy/1/9/ |
多级app目录进行分类
如果存在多个app目录,每个app目录下面都可能存在同名的函数或者url,那么这种多级的路由方式,可以通过在主url文件中配置include指向各app目录下的子url文件,然后在app各自的目录下,再配置自己的url文件。
比如:
1 2 3 4 5 | urlpatterns = [ url(r '^admin/' , admin.site.urls), url(r '^cmdb/' , include( "app01.urls" )), url(r '^monitor/' , include( "app02.urls" )), ] |
url.py
1 2 3 4 5 6 7 8 9 | urlpatterns = [ url(r '^login/' , views.login), url(r '^index/' , views.index), url(r '^user_info/' , views.user_info), url(r '^userdetail-(?P<nid>\d+)/' , views.user_detail), url(r '^userdel-(?P<nid>\d+)/' , views.user_del), url(r '^useredit-(?P<nid>\d+)/' , views.user_edit), url(r '^orm/' , views.orm), ] |
views.py
1 2 3 4 5 6 7 8 9 10 | def user_info(request): if request.method = = "GET" : user_list = models.UserInfo.objects. all () group_list = models.UserGroup.objects. all () return render(request, 'user_info.html' , { 'user_list' : user_list, "group_list" : group_list}) elif request.method = = 'POST' : u = request.POST.get( 'user' ) p = request.POST.get( 'pwd' ) models.UserInfo.objects.create(username = u,password = p) return redirect( '/cmdb/user_info/' ) |
url.py
1 2 3 | urlpatterns = [ url(r '^login/' , views.login), ] |
view.py
1 2 | def login(request): return HttpResponse( 'APP02,login' ) |
访问不同app下的效果
Url里面还可以设置默认值,比如说我们可以定义一个字典
1 | url(r '^index/' , views.index, { 'name' : 'root' }), |
在index这个函数里面,我们就可以直接调用这个默认值
1 2 3 | def index(request,name): print (name) return HttpResponse( 'OK' ) |
最后一个是命名空间,这个和前面的多级App分类刚好是反过来的。
比如,有两个不同的Url都指向了同一个App
urls.py
1 2 | / admin / include( 'app01.urls' ,namespace = 'm1' ) / crm / include( 'app01.urls' ,namespace = 'm2' ) |
app01.urls
1 | / index / name = 'n1' |
函数里面生成url的话,需要指定一条明确的路径
1 | reverser( 'm1:n1' ) |