路由系统(URL)
因匹配关系从上到下依次匹配,建议匹配关系末尾使用"$",避免前面相同,而匹配出错
-
一对一
- url(r‘^home‘, views.Home.as_view()) 对应类
- url(r‘^detail‘, views.detail) 对应函数
-
一对多
- url(r‘^detail-(\d+).html‘, views.detail),
- url(r‘^detail-(\d+)-(\d+).html‘, views.detail) 形参位置顺序影响业务逻辑
- url(r‘^detail-(?P\d+)-(?P\d+).html‘, views.detail) 推荐
-
使用方法
def detail(request, *args, **kwargs): # kwargs 以字典形式取值 detail_info = USER_DICT.get(kwargs.get("nid")) # args 以元组形式取值 detail_info = USER_DICT.get(args[0]) def detail(request, nid, uid): detail_info = USER_DICT.get(nid)
-
name 路由对应名称
对URL路径关系进行命名,以后可以根据此名称生成自己想要的URL
通常情况(WEB框架通用方法) url对应关系名称修改,html的form标签中action内容对应修改 例如: url(r‘^indexddhhddjdfjd‘, views.index), <form action="/indexddhhddjdfjd" method="post"> django特有方法 (1) 仅需要修改url对应关系即可,无需修改html 例如: url(r‘^bjbjbj‘, views.index, name="index"), <form action="{% url ‘index‘ %}" method="post"> def index(request): pass 缺点:仅能访问http://127.0.0.1:8000/bjbjbj/ 但http://127.0.0.1:8000/bjbjbj/1/就访问失败 (2)支持访问http://127.0.0.1:8000/bjbjbj/5/1 url(r‘^bjbjbj/(\d+)/(\d+)‘, views.index, name="index"), <form action="{% url ‘index‘ 1 2 %}" method="post"> def index(request, nid, uid): pass 缺点:访问的是http://127.0.0.1:8000/bjbjbj/5/1, 但生成的是<form action="/bjbjbj/1/2" method="post"> (3)访问和生成一致 url(r‘^bjbjbj/(\d+)/(\d+)‘, views.index, name="index"), <form action={{ request.path_info }} method="post"> def index(request, nid, uid): pass (4)也可以在views.py中生成 url(r‘^bjbjbj‘, views.index, name="index"), <form action={{ request.path_info }} method="post"> def index(request): from django.urls import reverse v = reverse("index") print(v) return render(request, ‘index.html‘, {"user_dict": USER_DICT}) url(r‘^bjbjbj/(\d+)/(\d+)‘, views.index, name="index"), <form action={{ request.path_info }} method="post"> def index(request, nid, uid): from django.urls import reverse v = reverse("index", args=(1, 2)) print(v) return render(request, ‘index.html‘, {"user_dict": USER_DICT}) url(r‘^bjbjbj/(?P<nid>\d+)/(?P<uid>\d+)‘, views.index, name="index"), <form action={{ request.path_info }} method="post"> 或者<form action="{% url ‘index‘ nid=1 uid=3 %}" method="post"> def index(request, nid, uid): from django.urls import reverse v = reverse("index", kwargs={"nid":nid, "uid":uid}) print(v) return render(request, ‘index.html‘, {"user_dict": USER_DICT}) 总结: {{ request.path_info }} 当前的url,操作后,还在当前操作页 {% url "index" 3 6 %} 在当前页操作,操作后,跳转到指定页,定制 url(r‘^fine/‘, views.index, name="i1"), url(r‘^today/(\d+)/(\d+)‘, views.index, name="i2"), url(r‘^buy/(?P<nid>\d+)/(?P<uid>\d+)‘, views.index, name="i3"), def func(request, *args, **kwargs): from django.urls import reverse url1 = reverse("i1") # fine/ url2 = reverse("i2", args=(1,2,)) # yug/1/2/ url3 = reverse("i3", kwargs={"pid":1, "nid":9}) # buy/1/9/ xxx.html {% url "i1" %} # fine/ {% url "i2" 1 2 %} # yug/1/2/ {% url "i3" pid=1 nid=9 %} # buy/1/9/
-
路由分发 工程 urls.py 写分类
from django.conf.urls import include urlpatterns = [ url(r‘^cmdb/‘, include("app01.urls")), url(r‘^monitor/‘, include("app02.urls")), ]
app02之urls.py 写app02的具体路由对应关系
from django.conf.urls import url from app02 import views urlpatterns = [ url(r‘^login‘, views.login), ]
app01之urls.py 写app01的具体路由对应关系
同app02的url.py,和之前的写法一样
客户端访问方式改为
http://127.0.0.1:8000/cmdb/login http://127.0.0.1:8000/monitor/login
注:路由分发"进"(客户端请求)起作用,但"出"(发回客户端)需要明确表明
html要修改
<form action="/monitor/login" method="post">
或者app的views.py中
return redirect(‘/monitor/index1‘)
-
默认值
-
命名空间
客户端访问形式一:http://127.0.0.1:8000/detail?nid=2
默认页面是动态的
urls.py
url(r‘^detail‘, views.detail),
url(r‘^login‘, views.login),
views.py
USER_DICT={
"1":{"name": "root1", "email": "[email protected]"},
"2":{"name": "root2", "email": "[email protected]"},
"3":{"name": "root3", "email": "[email protected]"},
"4":{"name": "root4", "email": "[email protected]"},
}
def detail(request):
nid = request.GET.get("nid")
detail_info = USER_DICT.get(nid)
return render(request, "detail.html", {"detail_info":detail_info})
def index(request):
return render(request, ‘index.html‘, {"user_dict": USER_DICT})
index.html
<ul>
{% for k, v in user_dict.items %}
<li><a target="_blank" href="/detail?nid={{ k }}">{{ v.name }}</a></li>
{% endfor %}
</ul>
detail.html
<body>
<h1>详细信息</h1>
<h6>用户名:{{ detail_info.name }}</h6>
<h6>邮箱:{{ detail_info.email }}</h6>
</body>
客户端访问形式二:http://127.0.0.1:8000/detail-1-10.html
默认页面是静态的
views.py
这里要求与urls对应关系的参数个数一致
def detail(request, nid, uid):
detail_info = USER_DICT.get(nid)
return render(request, "detail.html", {"detail_info": detail_info})
若参数不确定时,可以写成
def detail(request, *args, **kwargs):
pass
urls.py
url(r‘^detail-(?P<nid>\d+)-(?P<uid>\d+).html‘, views.detail)
index.html
<ul>
{% for k, v in user_dict.items %}
<li><a target="_blank" href="/detail-{{ k }}.html">{{ v.name }}</a></li>
{% endfor %}
</ul>
detail.html 同上
视图
request.GET
request.POST
request.FILES(文件操作)
FBV function base view
urls.py
index -> 函数名
url(r‘^login‘, views.login),
请求来了,执行函数名对应的方法
views.py
def func(request):
pass
CBV class base view
urls.py
home -> 类
url(r‘^home‘, views.Home.as_view()),
注:as_view()为固定写法
请求来了,执行类中具体的方法
views.py
from django.views import View
class Home(View):
def dispatch(self, request, *args, **kwargs):
print("before")
result = super(Home, self).dispatch(request, *args, **kwargs)
print("after")
return result
def get(self, request):
print(request.method)
return render(request, ‘home.html‘)
def post(self, request):
print(request.method)
return render(request, ‘home.html‘)
装饰器
默认数据交互规则
- GET: 获取数据
- 浏览器默认方法
- 将输入的内容,填充到url中,url上内看到填写内容,再发放到服务端
- POST:提交数据
- 将输入内容,填充到body中,再发放到服务端
- GET方法和POST方法
- get方法和post方法传输的内容,都可以通过抓包方式,获取内容
- 不存在,那种方式更安全之说。
- PUT
- DELETE
- HEAD
- OPTION
获取用户提交信息
-
输入框
- request.POST.get("username")
-
单选框
- request.POST.get("gender")
-
多选框
- request.POST.getlist("favor")
-
select
- 默认单选
- request.POST.get("city")
- 有multiple,可多选
- request.POST.getlist("city")
- 默认单选
-
文件 form 表单头需要添加 enctype="multipart/form-data"
- 文件名
- obj.name
- 文件内容(上传文件)
obj = request.FILES.get("file") print(type(obj.name), obj.name) file_path = os.path.join("upload", obj.name) with open(file_path, mode="wb") as f: for part in obj.chunks(): f.write(part)
- 文件名