三大塊除了M、V、T,接下來學習一些其它的知識點,這些知識點不在三大塊範圍內,Django提供了這些功能後,能夠幫助咱們更快更好的完成開發。javascript
主要知識點以下:css
項目中的CSS、圖片、js都是靜態文件。通常會將靜態文件放到一個單獨的目錄中,以方便管理。在html頁面中調用時,也須要指定靜態文件的路徑,Django中提供了一種解析的方式配置靜態文件路徑。靜態文件能夠放在項目根目錄下,也能夠放在應用的目錄下,因爲有些靜態文件在項目中是通用的,因此推薦放在項目的根目錄下,方便管理。html
1)在test5/settings.py文件中定義靜態文件存放的物理目錄。java
STATIC_URL = '/static/' STATICFILES_DIRS = [ os.path.join(BASE_DIR, 'static'), ]
2)在項目根目錄下建立static目錄,再建立img、css、js目錄。python
3)在booktest/views.py中定義視圖static_test。jquery
def static_test(request): return render(request,'booktest/static_test.html')
4)在booktest/urls.py中配置url。ajax
url(r'^static_test/$',views.static_test),
5)在templates/booktest/下建立static_test.html文件。數據庫
<html> <head> <title>靜態文件</title> </head> <body> <img src="/static/img/sg.png"/> </body> </html>
6)保存圖片到static/img/目錄下,名稱爲sg.png。django
爲了安全能夠經過配置項隱藏真實圖片路徑,在模板中寫成固定路徑,後期維護太麻煩,能夠使用static標籤,根據配置項生成靜態文件路徑。瀏覽器
1)修改templates/booktest/static_test.html以下:
<html> <head> <title>靜態文件</title> </head> <body> 修改前:<img src="/static/img/sg.png"/> <hr> 修改後:<img src="/abc/img/sg.png"/> <hr> 動態配置: {%load static from staticfiles%} <img src="{%static "img/sg.png" %}"/> </body> </html>
Django中的中間件是一個輕量級、底層的插件系統,能夠介入Django的請求和響應處理過程,修改Django的輸入或輸出。中間件的設計爲開發者提供了一種無侵入式的開發方式,加強了Django框架的健壯性,其它的MVC框架也有這個功能,名稱爲IoC。
Django在中間件中預置了五個方法,這五個方法的區別在於不一樣的階段執行,對輸入或輸出進行干預,方法以下:
1)初始化:無需任何參數,服務器響應第一個請求的時候調用一次,用於肯定是否啓用當前中間件。
def __init__(self): pass
2)處理請求前:在每一個請求上,request對象產生以後,url匹配以前調用,返回None或HttpResponse對象。
def process_request(self, request): pass
3)處理視圖前:在每一個請求上,url匹配以後,視圖函數調用以前調用,返回None或HttpResponse對象。
def process_view(self, request, view_func, *view_args, **view_kwargs): pass
4)處理響應後:視圖函數調用以後,全部響應返回瀏覽器以前被調用,在每一個請求上調用,返回HttpResponse對象。
def process_response(self, request, response): pass
5)異常處理:當視圖拋出異常時調用,在每一個請求上調用,返回一個HttpResponse對象。
def process_exception(self, request,exception): pass
中間件是一個獨立的python類,,能夠定義這五個方法中的一個或多個。
1)在booktest/目錄下建立middleware.py文件,代碼以下:
class my_mid: def __init__(self): print '--------------init' def process_request(self,request): print '--------------request' def process_view(self,request, view_func, *view_args, **view_kwargs): print '--------------view' def process_response(self,request, response): print '--------------response' return response
2)在test5/settings.py文件中,向MIDDLEWARE_CLASSES項中註冊。
3)修改booktest/views.py中視圖index。
def index(request): print '======index======' return render(request,'booktest/index.html')
4)運行服務器,命令行中效果以下圖:
3)刷新頁面,命令行中效果以下圖:
1)在booktest/middleware.py中定義兩個異常類以下:
class exp1: def process_exception(self,request,exception): print '--------------exp1' class exp2: def process_exception(self,request,exception): print '--------------exp2'
2)在test5/settings.py文件中,向MIDDLEWARE_CLASSES項中註冊。
3)修改booktest/views.py中視圖index。
def index(request): print '======index======' raise Exception('自定義異常') return render(request,'booktest/index.html')
總結:若是多個註冊的中間件類中都有process_exception的方法,則先註冊的後執行
內容發佈的部分由網站的管理員負責查看、添加、修改、刪除數據,開發這些重複的功能是一件單調乏味、缺少創造力的工做,爲此,Django可以根據定義的模型類自動地生成管理模塊。
在第一部分對管理站點作了簡單介紹,如今作詳細講解。在Django項目中默認啓用Admin管理站點。
1)準備工做:建立管理員的用戶名和密碼。
python manage.py createsuperuser
按提示填寫用戶名、郵箱、密碼。
2)使用:在應用的admin.py中註冊模型類
例:打開booktest/admin.py文件,註冊地區模型。
from django.contrib import admin from booktest.models import * admin.site.register(AreaInfo)
3)輸入以下網址:
登陸成功後,能夠看到AreaInfos,能夠進行增長、修改、刪除、查詢的管理。
列表頁顯示效果以下圖:
類ModelAdmin能夠控制模型在Admin界面中的展現方式,主要包括在列表頁的展現方式、添加修改頁的展現方式。
1)在booktest/admin.py中,註冊模型類前定義管理類AreaAdmin。
class AreaAdmin(admin.ModelAdmin): pass
管理類有兩種使用方式:
註冊參數:打開booktest/admin.py文件,註冊模型類代碼以下:
admin.site.register(AreaInfo,AreaAdmin)
裝飾器:打開booktest/admin.py文件,在管理類上註冊模型類,代碼以下:
@admin.register(AreaInfo) class AreaAdmin(admin.ModelAdmin): pass
接下來介紹如何控制列表頁、增長修改頁展現效果。
每頁中顯示多少條數據,默認爲每頁顯示100條數據,屬性以下:
list_per_page=100
1)打開booktest/admin.py文件,修改AreaAdmin類以下:
class AreaAdmin(admin.ModelAdmin): list_per_page = 10
2)在瀏覽器中查看區域信息的列表頁面,效果以下圖:
頂部顯示的屬性,設置爲True在頂部顯示,設置爲False不在頂部顯示,默認爲True。
actions_on_top=True
底部顯示的屬性,設置爲True在底部顯示,設置爲False不在底部顯示,默認爲False。
actions_on_bottom=False
1)打開booktest/admin.py文件,修改AreaAdmin類以下:
class AreaAdmin(admin.ModelAdmin): ... actions_on_top = True actions_on_bottom = True
2)在瀏覽器中刷新效果以下圖:
屬性以下:
list_display=[模型字段1,模型字段2,...]
1)打開booktest/admin.py文件,修改AreaAdmin類以下:
class AreaAdmin(admin.ModelAdmin): ... list_display = ['id','atitle']
2)在瀏覽器中刷新效果以下圖:
點擊列頭能夠進行升序或降序排列。
列能夠是模型字段,還能夠是模型方法,要求方法有返回值。
1)打開booktest/models.py文件,修改AreaInfo類以下:
class AreaInfo(models.Model): ... def title(self): return self.atitle
2)打開booktest/admin.py文件,修改AreaAdmin類以下:
class AreaAdmin(admin.ModelAdmin): ... list_display = ['id','atitle','title']
3)在瀏覽器中刷新效果以下圖:
方法列是不能排序的,若是須要排序須要爲方法指定排序依據。
admin_order_field=模型類字段
1)打開booktest/models.py文件,修改AreaInfo類以下:
class AreaInfo(models.Model): ... def title(self): return self.atitle title.admin_order_field='atitle'
2)在瀏覽器中刷新效果以下圖:
列標題默認爲屬性或方法的名稱,能夠經過屬性設置。須要先將模型字段封裝成方法,再對方法使用這個屬性,模型字段不能直接使用這個屬性。
short_description='列標題'
1)打開booktest/models.py文件,修改AreaInfo類以下:
class AreaInfo(models.Model): ... title.short_description='區域名稱'
2)在瀏覽器中刷新效果以下圖:
沒法直接訪問關聯對象的屬性或方法,能夠在模型類中封裝方法,訪問關聯對象的成員。
1)打開booktest/models.py文件,修改AreaInfo類以下:
class AreaInfo(models.Model): ... def parent(self): if self.aParent is None: return '' return self.aParent.atitle parent.short_description='父級區域名稱'
2)打開booktest/admin.py文件,修改AreaAdmin類以下:
class AreaAdmin(admin.ModelAdmin): ... list_display = ['id','atitle','title','parent']
3)在瀏覽器中刷新效果以下圖:
右側欄過濾器
屬性以下,只能接收字段,會將對應字段的值列出來,用於快速過濾。通常用於有重複值的字段
list_filter=[]
1)打開booktest/admin.py文件,修改AreaAdmin類以下:
class AreaAdmin(admin.ModelAdmin): ... list_filter=['atitle']
2)在瀏覽器中刷新效果以下圖:
屬性以下,用於對指定字段的值進行搜索,支持模糊查詢。列表類型,表示在這些字段上進行搜索。
search_fields=[]
1)打開booktest/admin.py文件,修改AreaAdmin類以下:
class AreaAdmin(admin.ModelAdmin): ... search_fields=['atitle']
2)在瀏覽器中刷新效果以下圖:
1)打開booktest/models.py文件,修改模型類,爲屬性指定verbose_name參數,即第一個參數
class AreaInfo(models.Model): atitle=models.CharField('標題',max_length=30)#名稱 ...
2)在瀏覽器中刷新效果以下圖:
屬性以下:
fields=[]
1)點擊某行ID的連接,能夠轉到修改頁面,默認效果以下圖:
2)打開booktest/admin.py文件,修改AreaAdmin類以下:
class AreaAdmin(admin.ModelAdmin): ... fields=['aParent','atitle']
3)刷新瀏覽器效果以下圖:
在下拉列表中輸出的是對象的名稱,能夠在模型類中定義str方法用於對象轉換字符串。
1)打開booktest/models.py文件,修改AreaInfo類,添加str方法。
class AreaInfo(models.Model): ... def __str__(self): return self.atitle
2)刷新瀏覽器效果以下圖:
屬性以下:
fieldset=( ('組1標題',{'fields':('字段1','字段2')}), ('組2標題',{'fields':('字段3','字段4')}), )
1)打開booktest/admin.py文件,修改AreaAdmin類以下:
class AreaAdmin(admin.ModelAdmin): ... # fields=['aParent','atitle'] fieldsets = ( ('基本', {'fields': ['atitle']}), ('高級', {'fields': ['aParent']}) )
2)刷新瀏覽器效果以下圖:
在一對多的關係中,能夠在一端的編輯頁面中編輯多端的對象,嵌入多端對象的方式包括表格、塊兩種。 類型InlineModelAdmin:表示在模型的編輯頁面嵌入關聯模型的編輯。子類TabularInline:以表格的形式嵌入。子類StackedInline:以塊的形式嵌入。
1)打開booktest/admin.py文件,建立AreaStackedInline類。
class AreaStackedInline(admin.StackedInline): model = AreaInfo#關聯子對象 extra = 2#額外編輯2個子對象
2)打開booktest/admin.py文件,修改AreaAdmin類以下:
class AreaAdmin(admin.ModelAdmin): ... inlines = [AreaStackedInline]
3)刷新瀏覽器效果以下圖:
能夠用表格的形式嵌入。
1)打開booktest/admin.py文件,建立AreaTabularInline類。
class AreaTabularInline(admin.TabularInline): model = AreaInfo#關聯子對象 extra = 2#額外編輯2個子對象
2)打開booktest/admin.py文件,修改AreaAdmin類以下:
class AreaAdmin(admin.ModelAdmin): ... inlines = [AreaTabularInline]
3)刷新瀏覽器效果以下圖:
在python中進行圖片操做,須要安裝包PIL。
pip install Pillow==3.4.1
在Django中上傳圖片包括兩種方式:
上傳圖片後,將圖片存儲在服務器上,而後將圖片的路徑存儲在表中。
將模型類的屬性定義成models.ImageField類型。
1)打開booktest/models.py文件,定義模型類PicTest。
class PicTest(models.Model): pic = models.ImageField(upload_to='booktest/')
2)回到命令行中,生成遷移。
python manage.py makemigrations
3)打開booktest/migrations/0001_initial.py文件,刪除AreaInfo部分,由於這個表已經存在。
4)回到命令行中,執行遷移。
python manage.py migrate
5)由於當前沒有定義圖書、英雄模型類,會提示「是否刪除」,輸入「no」後回車,表示不刪除。
6)打開test5/settings.py文件,設置圖片保存路徑。
由於圖片也屬於靜態文件,因此保存到static目錄下。
MEDIA_ROOT=os.path.join(BASE_DIR,"static/media")
1)打開booktest/admin.py文件,註冊PicTest。
from django.contrib import admin from booktest.models import * admin.site.register(PicTest)
2)運行服務器,輸入以下網址。
3)點擊「Add」添加數據,打開新頁面。
4)選擇圖片,點擊「save」按鈕完成圖片上傳。 5)回到數據庫命令行,查詢表pictest中的數據以下圖:
1)打開booktest/views.py文件,建立視圖pic_upload。
def pic_upload(request): return render(request,'booktest/pic_upload.html')
2)打開booktest/urls.py文件,配置url。
url(r'^pic_upload/$', views.pic_upload),
3)在templates/booktest/目錄下建立模板pic_upload.html。
在模板中定義上傳表單,要求以下:
<html> <head> <title>自定義上傳圖片</title> </head> <body> <form method="post" action="/pic_handle/" enctype="multipart/form-data"> {%csrf_token%} <input type="file" name="pic"/><br> <input type="submit" value="上傳"> </form> </body> </html>
4)打開booktest/views.py文件,建立視圖pic_handle,用於接收表單保存圖片。
request對象的FILES屬性用於接收請求的文件,包括圖片。
from django.conf import settings from django.http import HttpResponse ... def pic_handle(request): f1=request.FILES.get('pic') fname='%s/booktest/%s'%(settings.MEDIA_ROOT,f1.name) with open(fname,'wb') as pic: for c in f1.chunks(): pic.write(c) return HttpResponse('OK')
5)打開booktest/urls.py文件,配置url。
url(r'^pic_handle/$', views.pic_handle),
6)運行服務器
選擇文件後點擊按鈕上傳圖片。
Django提供了數據分頁的類,這些類被定義在django/core/paginator.py中。 類Paginator用於對列進行一頁n條數據的分頁運算。類Page用於表示第m頁的數據。
1)在booktest/views.py文件中建立視圖page_test。
from django.core.paginator import Paginator from booktest.models import AreaInfo ... #參數pIndex表示:當前要顯示的頁碼 def page_test(request,pIndex): #查詢全部的地區信息 list1 = AreaInfo.objects.filter(aParent__isnull=True) #將地區信息按一頁10條進行分頁 p = Paginator(list1, 10) #若是當前沒有傳遞頁碼信息,則認爲是第一頁,這樣寫是爲了請求第一頁時能夠不寫頁碼 if pIndex == '': pIndex = '1' #經過url匹配的參數都是字符串類型,轉換成int類型 pIndex = int(pIndex) #獲取第pIndex頁的數據 list2 = p.page(pIndex) #獲取全部的頁碼信息 plist = p.page_range #將當前頁碼、當前頁的數據、頁碼信息傳遞到模板中 return render(request, 'booktest/page_test.html', {'list': list2, 'plist': plist, 'pIndex': pIndex})
2)在booktest/urls.py文件中配置url
url(r'^page(?P<pIndex>[0-9]*)/$', views.page_test),
3)在templates/booktest/目錄下建立page_test.html模板文件。
<html> <head> <title>分頁</title> </head> <body> 顯示當前頁的地區信息:<br> <ul> {%for area in list%} <li>{{area.id}}--{{area.atitle}}</li> {%endfor%} </ul> <hr> 顯示頁碼信息:當前頁碼沒有連接,其它頁碼有連接<br> {%for pindex in plist%} {%if pIndex == pindex%} {{pindex}} {%else%} <a href="/page{{pindex}}/">{{pindex}}</a> {%endif%} {%endfor%} </body> </html>
4)運行服務器
5)點擊頁碼數字,效果以下圖:
本示例講解在Django中使用jquery的ajax進行數據交互。 jquery框架中提供了$.ajax、$.get、$.post方法,用於進行異步交互,因爲Django中默認使用CSRF約束,推薦使用$.get。
示例:實現省市區的選擇。
最終實現效果如圖:
1)將jquery文件拷貝到static/js/目錄下。
2)打開booktest/views.py文件,定義視圖area1,用於顯示下拉列表。
#提供顯示下拉列表的控件,供用戶操做 def area1(request): return render(request,'booktest/area1.html')
3)打開booktest/urls.py文件,配置url。
url(r'^area1/$', views.area1),
4)在templates/booktest/目錄下建立area1.html。
<html> <head> <title>省市區列表</title> <script type="text/javascript" src="/static/js/jquery-1.12.4.min.js"></script> <script type="text/javascript"> $(function(){ //頁面加載完成後獲取省信息,並添加到省select $.get('/area2/',function(dic) { pro=$('#pro') $.each(dic.data,function(index,item){ pro.append('<option value='+item[0]+'>'+item[1]+'</option>'); }) }); //爲省select綁定change事件,獲取市信息,並添加到市select $('#pro').change(function(){ $.get('/area3_'+$(this).val()+'/',function(dic){ city=$('#city'); city.empty().append('<option value="">請選擇市</option>'); dis=$('#dis'); dis.empty().append('<option value="">請選擇區縣</option>'); $.each(dic.data,function(index,item){ city.append('<option value='+item[0]+'>'+item[1]+'</option>'); }) }); }); //爲市select綁定change事件,獲取區縣信息,並添加到區縣select $('#city').change(function(){ $.get('/area3_'+$(this).val()+'/',function(dic){ dis=$('#dis'); dis.empty().append('<option value="">請選擇區縣</option>'); $.each(dic.data,function(index,item){ dis.append('<option value='+item[0]+'>'+item[1]+'</option>'); }) }) }); }); </script> </head> <body> <select id="pro"> <option value="">請選擇省</option> </select> <select id="city"> <option value="">請選擇市</option> </select> <select id="dis"> <option value="">請選擇區縣</option> </select> </body> </html>
5)運行服務器瀏覽效果以下圖:
6)打開booktest/views.py文件,定義視圖area2,用於獲取省信息。
from django.http import JsonResponse ... #獲取省信息 def area2(request): list = AreaInfo.objects.filter(aParent__isnull=True) list2 = [] for item in list: list2.append([item.id, item.atitle]) return JsonResponse({'data': list2})
7)打開booktest/urls.py文件,配置url。
url(r'^area2/$', views.area2),
8)在瀏覽器中輸入網址,瀏覽效果以下圖:
9)打開booktest/views.py文件,定義視圖area3,用於根據編號獲取對應的子級信息,若是傳遞的是省編號則獲取市信息,若是傳遞的是市編號則獲取區縣信息。
#根據pid查詢子級區域信息 def area3(request, pid): list = AreaInfo.objects.filter(aParent_id=pid) list2 = [] for item in list: list2.append([item.id, item.atitle]) return JsonResponse({'data': list2})
10)打開booktest/urls.py文件,配置url。
url(r'^area3_(\d+)/$', views.area3),
11)在瀏覽器中輸入以下網址,瀏覽效果以下圖:
12)在瀏覽器中輸入以下網址,選擇效果以下圖: