3)django-路由系统url
一:django路由系统说明
路由都在urls文件里,它将浏览器输入的url映射到相应的业务处理逻辑
二:django 常用路由系统配置
1)URL常用有模式一FBV(function base view)
url(r'^index/', views.index) 一个URL地址对应一个views中方法
2)URL常用有模式一CBV(class base view)
url(r'^home/', views.Home.as_view())
#动太路由,一类URL,以不同的方式执行不同的方法,比如get,post等,view中也调用不同的get,post方法
3)url中传递参数,分普通传递参数和带命名的参数
A)普通传递参数
url(r'^detail-(\d+)-(\d+).html',views.detail)传递两个参数
def detail(request,nid,uid)和上面严格的按顺序对应,
B)带命名的参数: (?P<name>…) named group 带命名的组
url(r'^detail-(?P<nid>\d+)-(?P<uid>\d+).html',views.detail) 第一个传递给nid,第二个给uid
def detail(request,nid,uid)==def detail(request,uid,nid)参数位置不对,也可以正确传递
传递参数推荐使用带命名的参数。
4)url中name属性:name对URL路由关系进行命名
写法如下:
url(r'^index11/', views.index,name="index"),
表示url有个名字,就是不管前面r^index/'怎么变,我们都可以通过name调用
比如:原url(r'^index11/', views.index,name="index"), 该为url(r'^index/', views.index,name="index")
这个时候模块中form的action 也要相应做调用。
<form action="/index11/" method="post">
调整为<form action="/index/" method="post">
如何避免这种情况,可以采集如下办法:
<form action="{% url "index"%}" method=post">
用法:<form action="{% url "url中的name"%}" method=post">
注:假如有变量a 和b如何传递
<form action="{% url "index" a b %}" method=post">
特别情况1)上面的name只能获取到前缀url:比如url(r'^index11/', views.index,name="index"), 中的index11。如果url中带有参数就需要做相应的调整
A)带参数url使用方法1
url(r'^index11/(\d+)', views.index,name="indexx"),
对应URL地址:http://127.0.0.1/index11/1
模板中调整:<form action="{% url "indexx"% 1}" method="post"> 1就是传递的参数,但是这里1是写死的,如果参数变了调整相当麻烦,如何解决?
B)带参数url使用方法2
可以通过views中request解决。request.path_info有访问地址,reqeust是传递给模板的(render中第一个参数)
模板中调整<form action="{{request.path_info}}" method="post">,但是要注意这里跳转还是当前的页
C)带参数url使用方法3
还可以通过view中方法reveser实现参数传递
示例:
还可以通过view中方法实现reveser
1)普通传递
url(r'^index11/(\d+)', views.index,name="indexx")
def index(request,nid):
print(request.path_info)
from django.urls import reverse
v=reverse("indexx",args=(90,))传递参数
print(v)
return render(request,"index.html",{"USER_DICT":USER_DICT})
<form action="{% url "index11" 90 %}" method="post">
2)带命名传递
url(r'^index11/(?P<nid>\d+)', views.index,name="indexx") v=reverse("indexx",kwargs=(90,))传递参数 <form action="{% url "index11" nid=1%}" method="post">
name总结:
总结: name对URL路由关系进行命名, 存在的目的:##以后可以根据此名称生成自己想要的URL### url(r'^index11/', views.index,name="indexx"), 模板语言: {%%url "indexxx" %} {%%url "indexxx" 3 %} 加个参数,可以跳转到指定的页面,可以加很多参数 {%%url "indexxx" 3 6%}两个参数 <form action="{{request.path_info}}" method="post"> 跳转还是回当前页 还可以通过view中方法实现reveser url(r'^index11/(\d+)', views.index,name="indexx") def index(request,nid): print(request.path_info) from django.urls import reverse v=reverse("indexx",args=(90,))传递参数 print(v) return render(request,"index.html",{"USER_DICT":USER_DICT}) url(r'^index11/(?P<nid>\d+)', views.index,name="indexx") v=reverse("indexx",kwargs=(90,))传递参数 <form action="{% url "index11" nid=1%}" method="post"> name一共就3种存在形式 url(r'^index11/', views.index,name="i1") url(r'^index11/(\d+)/(\d+)', views.index,name="i2") url(r'^index11/(?P<pid>\d+)(?P<nid>\d+)', views.index,name="i3") def func(request,*args,**kwargs): from django.urls import reverse url1=reverse("i1") #index11 url2=reverse("i2",args=(1,2)) #index11/1/2 url3=reverse("i3",kwargs={'pid':1,'nid':9}) #index11/1/9 XXX.html {% url "i1"%} #index11 {% url "i1" 1 2%} #index11/1/2 {% url "i1" pid=1 nid=9%} #index11/1/9
5)URL自动路由(多级路由)
url访问会先到工程目录下面的urls中查询,再到app应用下查询urls.project.urls -->app.urls
主要为了解决一个工程下面多个APP有相同的访问路径。比如app01下面的login,app02下面又有login
用法: 使用inculde包含app下面的url
from django.conf.urls import url,include from django.contrib import admin urlpatterns = [ url(r'^admin/', admin.site.urls), url(r'^cmdb/',include("app01.urls")),#会根据cmdb自动分发 ] app.urls from django.conf.urls import url from app01 import views urlpatterns = [ url(r'^index11/(\d+)', views.index,name="indexx"), url(r'^login/', views.login), url(r'^home/', views.Home.as_view()), url(r'^detail-(\d+).html',views.detail), ]
示例2:
project/urls.py
from django.conf.urls import url,include
from django.contrib import admin
urlpatterns = [
url(r'^cmdb/', include("app01.urls")),
url(r'^monitor/', include("app02.urls")),
]
app01/urls.py
from django.conf.urls import url,include
from django.contrib import admin
from app01 import views
urlpatterns = [
url(r'^login/', views.login),
]
app02/urls.py
from django.conf.urls import url,include
from django.contrib import admin
from app02 import views
urlpatterns = [
url(r'^login/', views.login),
]
6)默认值
默认就是URL给视图传递个默认值
用法如下:
/index/ {""web":"root"},给视图传递了默认参数web
def func(request,web)
urls.py url(r'index$',views.index,{"name":"index"}), views.py def index(request,name): return HttpResponse(name)
7)命名空间namespace,就是自动路由情况下,可能有多个指向同一个app.urls。为了区分是那个URL过来的,用namspace
/crm/ include("app01.urls")
/crm/ include("app02.urls") 从上到下匹配
多个分发指定到同一个app.urls,需要确认是那个url
/admin/ include("app01.urls")
/crm/ include("app01.urls")
通过namespace+name可以反转确定是那个url
示例
#project.urls from django.conf.urls import url,include from django.contrib import admin urlpatterns = [ url(r'^admin/', admin.site.urls), url(r'^a/', include("app01.urls",namespace="author")), url(r'^b/', include("app01.urls",namespace="publish")), ] #app.urls from django.conf.urls import url from app01 import views urlpatterns = [ url(r'^index/', views.index,name="index"), ] views from django.shortcuts import render,HttpResponse from django.urls import reverse # Create your views here. def index(request): v=reverse("author:index") #"namespace:name" 可以确定是那个url print(v) return HttpResponse(v)
#把绝对的url转相对的url from django.core.urlresolvers import resolve resolve_obj=resolve(request.path)