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