1、内容概要:
2、上节回顾
3、Django 视图–views
一、获取用户多个数据及文件上传
二、FBV 和 CBV
三、装饰器
4、Django模板补充
- Django模板语言循环字典
5、Django 路由系统
一、一对一:一个url对于一个函数或者一个类
2.一、一对多:一类url对应一个函数或者一个类
2.二、一对多,用法总结
三、name参数
四、url 路由分发机制
五、默认值
六、命名空间html
一、路由系统——urlspython
二、视图web
三、模板正则表达式
四、ORM操做数据库
select * from tb where id > 1django
# 对应关系app
models.tb.objects.filter(id__gt=1)框架
models.tb.objects.filter(id=1)函数
models.tb.objects.filter(id__lt=1)post
一、Django请求生命周期
客户端 -> URL对应关系(匹配) -> 视图函数 -> 返回用户字符串
客户端 -> URL对应关系(匹配) -> 视图函数 -> 打开一个HTML文件,读取内容
2.一、建立django projcet
django-admin startproject mysite .. mysite mysite - 配置文件 - urls.py - settings.py
2.2建立django project app
cd mysite python manage.py startapp cmdb mysite mysite …… cmdb - views.py - admin.py - models.py # 建立数据库表
三、配置
模板路径 静态文件路径 # 注释 CSRF
四、编写程序
a. url.py
/index/ -> func
b. views.py
def func(request): # request:包含全部的请求数据 ... return HttpResponse('字符串') # 返回字符串 return render(request, 'index.html', {''}) # 返回模板内容 retrun redirect('URL') # 返回url
c. 模板语言
return render(request, 'index.html', {'li': [11,22,33]}) {% for item in li %} # 模板语音for循环 <h1>{{item}}</h1> {% endfor %} *********** 去索引:索引用点 ********** <h2> {{item[0] }} </h2> # 不能这么用, <h2> {{item.0 }} </h2> # 正确写法
request.GET # 获取相应信息中get发送的数据 request.POST # 获取相应信息中post发送的数据 request.FILES # 获取相应信息中发送的文件数据 PS: # get和post都是日后台发送数据,只是get信息在网址中,post信息包含着数据内,每每: GET: # 获取数据 POST: # 提交数据
request.POST.getlist() # get只能获取一个值,像复选框、多选下拉框时,须要用getlist获取
# 上传文件,form标签作特殊设置 enctype="multipart/form-data" obj = request.FILES.get('fafafa') # 获取上传文件对象 print( obj.name ) # 上传文件名称 f = open(obj.name, mode='wb') for item in obj.chunks(): # chunks():分块,一点一点取数据(生成器、迭代器) f.write(item) f.close()
示例:用户提交数据,后台接收响应数据,并进行处理
工程名:mysite,app名:cmdb,建立接收用户上传数据目录upload
mysite/urls.py
from django.contrib import admin from cmdb import views urlpatterns = [ url(r'^admin/', admin.site.urls), url(r'^login/', views.login), ]
cmdb/views.py
from django.shortcuts import render, redirect,HttpResponse def login(request): if request.method == "GET": return render(request, 'reg.html') elif request.method == "POST": # redio 单选框获取 redio = request.POST.get("gender") print("单选框的值:", redio) # checkbox 复选框获取 checkbox = request.POST.getlist("favor") print("复选框的值", checkbox) # 获取文件数据 obj = request.FILES.get("fafafa") print(obj, type(obj), obj.name) # 打印文件信息 import os file_path = os.path.join('upload', obj.name) with open (file_path, mode="wb") as f: for i in obj.chunks(): f.write(i) return render(request, "reg.html") else: # PUT, DELETE, HEAD, OPTION…… return redirect("/reg/")
templates/reg.html
<body> <form action="/login/" method="POST" enctype="multipart/form-data"> <p> <input type="text" name="user" placeholder="用户名" /> </p> <p> <input type="password" name="pwd" placeholder="密码" /> </p> <p>性别: 男:<input type="radio" name="gender" value="1"/> 女:<input type="radio" name="gender" value="2"/> </p> <p>爱好: 男:<input type="checkbox" name="favor" value="11"/> 女:<input type="checkbox" name="favor" value="22"/> </p> <p> <select name="city" multiple> <option value="sh">上海</option> <option value="bj">北京</option> <option value="tj">天津</option> </select> </p> <p> <input type="file" name="fafafa"/> </p> <input type="submit" value="提交"/> </form> </body>
像这种urls.py里匹配login,以后对应一个函数名。当匹配成功以后,就 执行views.py里的这个函数,函数里第一个参数封装了全部的用户请求信息。像这种叫FBV(function base view)
Django 里面还有一种:CBV(class base view)
/index/ -> 函数名
/index/ -> 类
上面都是FBV的方式,下面看看CBV写法:
urls.py
url(r'^home/', views.Home.as_view()), # CBV 固定用法
views.py
from django.views import View class Home(View): # 自定义的类必须继承View # 重写父类dispatch方法。程序定制时可使用 # 父类的dispatch方法,查找get、post等方法,基于反射实现的。 def dispatch(self, request, *args, **kwargs): print("相似装饰器:before") result = super(Home,self).dispatch(request, *args, **kwargs) print("相似装饰器:after") return result def get(self,request): # 定义get方法,get请求执行这个方法 print(request.method) return render(request, "home.html") def post(self,request): # 定义post方法,post请求执行这个方法 print(request.method,"post方式") return render(request, "home.html")
home.html
<body> <form action="/home/" method="POST"> <input type="text" name="user" /> <input type="submit" /> </form> </body>
后续文章补充
urls.py
url(r'^index/', views.index),
views.py
USER_DICT = { 'key1':{'name':'root1','eamil':'root@126.com'}, 'key2':{'name':'root2','eamil':'root@126.com'}, 'key3':{'name':'root3','eamil':'root@126.com'}, } def index(request): return render(request, 'index.html', {'user_dict': USER_DICT})
index.html
<body> {{ user_dict.k1 }} <ul> {# for row in user_dict # 默认循环显示的是key #} {% for k in user_dict.keys %} {# 循环字典:取key值 #} <li>{{ k }}</li> {% endfor %} </ul> <ul> {% for val in user_dict.values %} {# 循环字典:取value值 #} <li>{{ val }}</li> {% endfor %} </ul> <ul> {% for k,row in user_dict.items %} {# 循环字典:取key、value #} <li>{{ k }}-{{ row }}</li> {% endfor %} </ul> </body>
url(r'^index/', views.index), url(r'^home/', views.Home.as_view()),
如上循环字典的显示,若是是主机信息,应该显示主机名,点击才显示详细信息。实现以下:
urls.py
url(r'^index/', views.index), url(r'^detail-(key\d+).html/', views.detail),
注意:这里网址实现的方式是相似http://127.0.0.1/detail-key1.html
,而不是以前的detail?nid=key1
的方式。这种方式,对于网站权重来讲,搜索引擎更喜欢第一种方式。权重更好,会让搜索引擎觉得网页是静态的。
views.py
USER_DICT = { 'key1':{'name':'root1','eamil':'root@126.com'}, 'key2':{'name':'root2','eamil':'root@126.com'}, 'key3':{'name':'root3','eamil':'root@126.com'}, 'key4':{'name':'root4','eamil':'root@126.com'}, 'key5':{'name':'root5','eamil':'root@126.com'}, } def index(request): return render(request, 'index.html', {'user_dict': USER_DICT}) def detail(request, nid): # nid: url里正则二次过滤获取的值 detail_info = USER_DICT[nid] return render (request, 'detail.html', {'detail_info': detail_info})
index.html
<ul> {% for k,row in user_dict.items %} <li><a target="_blank" href="/detail-{{ k }}.html">{{ row.name }}</a></li> {% endfor %} </ul>
detail.html
<body> <h1>详细信息</h1> <h6>用户名:{{ detail_info.name }}</h6> <h6>邮箱:{{ detail_info.email }}</h6> </body>
urls.py:url(r'^detail-(key\d+).html/', views.detail),
views.py:def detail(request, nid):
访问网址:127.0.0.1/detail-key1.html
urls.py:url(r'^detail-(key\d+)-(\d+).html/', views.detail),
views.py:def detail(request, nid, uid):
访问网址:127.0.0.1/detail-key1-9.html
可见:url中二次匹配的值,和形参必须一一对应,但若是位置改了,里面的代码也得跟着改
urls.py:url(r'^detail-(?P<nid>\d+)-(?P<uid>\d+).html/', views.detail),
直接第一个匹配的传递给nid,第二个匹配的传递给uid,这样和views里的函数形参位置没有关系了。
views.py:def detail(request, nid, uid):
访问网址:127.0.0.1/detail-key1-9.html
url(r'^detail-(key\d+)-(\d+).html/', views.detail),
——> def detail(request, *args):
url(r'^detail-(?P<nid>\d+)-(?P<uid>\d+).html/', views.detail),
——> def detail(request, **kwargs):
以下内容:提交表单中action="/home/"
须要跟着url中网址的修改而修改。
home.html
<form action="/home/" method="POST"> <input type="text" name="user" /> <input type="submit" /> </form>
urls.py
url(r'^home/', views.home),
其余web框架也是这么实现的,要改两处都须要跟着修改。这里django给提供了一个便捷的用法,name参数。
name :django 简便用法
对URL路由关系进行命名, 之后能够根据此名称生成本身想要的URL
urls.py
url(r'^home/', views.home, name="homeee"),
home.html
<form action="{% url 'homeee' %}" method="POST"> <input type="text" name="user" /> <input type="submit" /> </form>
这样写上以后,url变了,只修改urls.py那里一处就能够了。
第二种:
# urls.py url(r'^yug/(\d+)/(\d+)/', views.index, name='i2'), # views.py def index(request,nid,uid): ......
# html {% url "i2" 1 2 %} # 成功匹配都,都跳转到: yug/1/2/
第三种:
# urls.py url(r'^buy/(?P<pid>\d+)/(?P<nid>\d+)/', views.index, name='i3'), # # buy/1/9/
# html {% url "i3" pid=1 nid=9 %} # buy/1/9/
上面是经过模板语音生成url,下面是经过reverse模块生成url,两种方式,实现功能同样。
url(r'^asdfasdfasdf/', views.index, name='ii'),
url(r'^yug/(\d+)/(\d+)/', views.index, name='i2'),
url(r'^buy/(?P<pid>\d+)/(?P<nid>\d+)/', views.index, name='i3'),
# views.py 文件 def func(request, *args, **kwargs): from django.urls import reverse # 根据名字反转生成一个url url1 = reverse('i1') # asdfasdfasdf/ url2 = reverse('i2', args=(1,2,)) # yug/1/2/ url3 = reverse('i3', kwargs={'pid': 1, "nid": 9}) # buy/1/9/
做用:用户完成某些操做后,跳转到指定页面。
# 注: request.path_info # 当前的url def index(request,nid): print(request.path_info) return render(request, 'index.html') <form action="{{ request.path_info }}" method="POST">
前面的urls对应关系都在urls.py内,若是多个app,都须要在这里引入。若是app多了,任何一个app的修改都会修改这一个urls文件。
在django里面,有一个url分发的机制。
urls.py
from django.conf.urls import include urlpatterns = [ url(r'^monitor/', include("app02.urls")), ]
app02/urls.py
from django.conf.urls import url from app02 import views urlpatterns = [ url(r'^login/', views.login), ]
访问http://127.0.0.1/monitor/login
,就访问的app02的login页面。
后续文章补充
转载请务必保留此出处:http://www.cnblogs.com/lgeng/articles/7363951.html
<!-- END -->
《版权说明》:本文--http://blog.csdn.net/fgf00/article/details/53649820