標籤:同步資料 ora create www 個人 http 視圖 lis 知識
我學習django的主要途徑是http://djangobook.com, 作者的書好像也出版了。作者的思路很清爽,講解淺顯易懂,該深入的地方深入,我很喜歡,比django官方文檔感覺好多了,官方文檔講解的太晦澀。這些隨筆是結合一些例子來細說django的學習要點與本人的學習心得。
有些中文部落格也講解了用django做一些小的項目,但是沒有細講django的原理,即為什麼要這樣做,我就個人的理解會細緻地講解各個部分的知識點。希望能協助更多人,也希望與更多人一起進步。
本人配置環境:(2017.6.20)
注意: 在windows中的檔案系統是用反斜線‘\‘來表示,但是即使是在windows系統下的django,在表示檔案路徑時依然用unix 風格的斜杠‘/‘
OS: win7
python:3.6.2
Django: 1.11.2
建立項目與應用
每個項目的前部分:建立項目與應用,把應用添加到settings.py 的‘INSTALLED_APP‘裡,在settings.py裡設定預設的資料庫,並同步資料庫資料的操作都是一樣的,就不具體敘述,可以參考我前面的例子。
我把這個上傳檔案的項目命名為disk, 項目名稱為mysite,建立完成後的結構如下:(disk/templates, disk/uploads, disk/forms.py 是我本人建立的,不是系統建立的。請忽略除mysite, disk以外的部分,與此例無關。)
# Application definitionINSTALLED_APPS = ( ‘django.contrib.admin‘, ‘django.contrib.auth‘, ‘django.contrib.contenttypes‘, ‘django.contrib.sessions‘, ‘django.contrib.messages‘, ‘django.contrib.staticfiles‘, ‘disk‘,)
建立Form類執行個體
為了簡單起見,在這個檔案上傳系統中,我們只設計兩個變數:上傳檔案的使用者改名,及上傳的檔案。Django中為使用者定義了一個django.forms庫,這個庫可以方便地進行form類的資料顯示及資料驗證,省去了很多使用者的代碼。django.forms庫用起來也方便,只需要在HTML檔案中需要增加<form> tag時,定義相應的 Form 類就可以。在以下的樣本中我們最終的頁面上只有一個<form> tag, 所以我們只需要定義一個Form類即可。Django 社區的慣例是把Form類單獨放在一個forms.py檔案中,我們最好也遵循這個規則。建立disk\forms.py檔案,並寫入:
# mysite\disk\forms.pyfrom django import formsclass UserForm(forms.Form): userName = forms.CharField(max_length = 20) uploadFile = forms.FileField()
可以看出Form類的文法與定義Model時的文法很像,對於每個變數都要定義它的域的屬性,這個我在下面的Model章節中會仔細再講。在UserForm中,我們定義了userName,它是字元屬性,還定義了uploadFile,它是檔案屬性。預設情況下這兩個變數都是不可為空的,如果為空白,則會在html頁面中顯示出相應的錯誤。
建立Models(資料庫層)
我們需要把使用者名稱和上傳的檔案路徑放到資料庫中, 所以在設計資料庫時需要兩個欄位:userName and uploadFile。在disk\models.py檔案中寫入:
# disk\models.pyfrom django.db import models# Create your models here.class User(models.Model): userName = models.CharField(max_length = 30) uploadFile = models.FileField(upload_to = ‘disk/upload/‘) def __str__(self): return self.userName
對於models的定義,要講的東西很多。
- 每個變數都要定義成某種類型的域(field),django會根據不同的域來決定某些事情。比如,域的類型會決定資料庫中該變數的資料類型(比如INTERGER, VARCHAR)。對於每個變數,在html顯示層,django把它定義成一個單獨的widget。最終是以什麼widget顯示變數也是與該域的類型有關的,比如一個CharField變數最終會以<input type= ‘text‘>的形式顯現。
- 以下是每種域類型變數的定義,來自http://www.djangobook.com/model-definition-reference/。為了保證釋義的完整性與準確性,我就不翻譯成中文了:
下張表是所有域通用的選擇性參數:
- FileFiled 說明:此類變數不支援primary_key, unique參數(見上表)。有兩個選擇性參數:upload_to和storage。‘upload_to‘定義的是一個本地的檔案路徑,這個路徑可以是個相對路徑,它會自動加到settings.py檔案中 BASE_DIR 目錄的後面。一般情況下,即使檔案上傳成功也不會儲存到資料庫中,除非顯性的調用save()函數。從效能上考慮,不會把上傳的檔案儲存體到資料庫中,而是把檔案的路徑儲存到資料庫中(如果調用了save()函數)。
- 在定義完models後,要把它同步到資料庫中,主要用兩個命令python manage.py makemigrations, python manage.py migrate
建立Views (邏輯層)
視圖views決定的是按照怎樣的邏輯收集處理資料,並把使用者的資料呈現給使用者;可以把它理解成使用者資料(資料庫)到最終呈現頁面(web頁面)的中間人。這部分一般就是純粹的python代碼。開啟mysite\disk\views.py檔案並寫入:
# mysite\disk\views.pyfrom django.shortcuts import renderfrom disk.forms import UserFormfrom disk.models import Userdef uploads(request): if request.method == ‘POST‘: userform = UserForm(request.POST, request.FILES) if userform.isValid(): user = User() user.userName = userform.cleaned_data[‘userName‘] user.uploadFile = userform.cleaned_data[‘uploadFile‘] user.save() return render(request, ‘uploadOK.html‘) else: userform = UserForm(initial ={‘userName‘: ‘sunshore‘}) return render(request, ‘upload.html‘, {‘userform‘: userform})
views.py檔案就把上文定義的UserForm和User (models檔案)引用了過來。
- 對於HttpRequest.POST對象,我們在上一節中講過,這裡不再敘述。
- HttpRequest.FILES對象也是一個“類字典”對象,它的‘key‘是檔案名稱,與html檔案中<input type = "file" name = "" />中的內容相同;‘key‘所對應的‘value‘ 是上傳的檔案。注意: 這個對象必須是在HttpRequest method = ‘POST‘ 並且<form> tag中包含 enctype="multipart/form-data"時才會有值,否則會返回一個空的類字典對象。
- django中Form類執行個體化後,可以通過isValid()函數來檢查資料是否有效;如果有效,則該執行個體就會有cleaned_data屬性,這是一個字典對象,包含的是Form類資料。
- 我們首先檢查HttpRequest是一個POST 方法,然後執行個體化Form類,如果執行個體化成功,就把資料存放區到資料庫中去。(當然最終儲存到資料庫中不是檔案本身,而是檔案路徑,上部分提到過)。如果HttpRequest不是POST方法,則把使用者名稱初始化成‘sunshore‘。
建立Templates(顯示層)
我們需要建立templates來定製資料的顯示。Django中將資料的處理與顯示分開了,資料的處理是在views.py中,資料的顯示是在templates裡。 預設情況下,mysite/mysite/settings.py檔案中的TEMPLATES定義‘APP_DIRS‘ = True, 也就是說django會到各個應用的檔案下尋找templates檔案夾,使用裡面定義的html檔案。
我們需要在mysite/disk/templates建立兩個html檔案:upload.html和uploadOK.html,並寫入:
# mysite\disk\templates\upload.html<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"><html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en"><head>
<style type="text/css">
ul.errorlist{
margin:0;
padding:0;
}
.errorlist li{
background-color: blue;
color: white;
display: block;
font-size: 1.0em;
margin: 0 0 1px;
padding: 0 10px;
}
</style>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /> <title>Upload File</title></head><body> <h1>User Upload Files</h1> <form action="" method="post" enctype="multipart/form-data" > {{userform.as_p}} {% csrf_token %} <input type="submit" value="ok"/> </form></body></html>
# mysite\disk\templates\uploadOK.html<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"><html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en"><head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /> <title>Upload OK</title></head><body> <p > Uploading Files Successfully </p> <a href= ‘upload‘>Back to upload file page </a></body></html>
- Form類會自動產生頁面的錯誤資訊,並以errorlist的形式返回結果。在html檔案中我們可以對errorlist進行CSS的定製,使得error資訊更為突出。這就是<style> ....</style>那段代碼的作用。
- 預設情況下,Form類顯示成員的排版格式有form.as_p, form.as_table, form.as_ul這三種形式,不同形式下成員的排列是不同的。比如本樣本中userform.as_p會顯示如下:
userform.as_table 顯示結果:
userform.as_ul 顯示結果:
我們可以根據自己的喜好來選擇成員的顯示形式。當然django也支援自己定製所有成員的顯示形式。感興趣的讀者可以參考:http://djangobook.com/tying-forms-views.
設定urlconf 檔案
這個是用Regex的方式定義了HttpRequest.url和views的對應關係。在mysite\urls.py檔案中輸入:
# mysite\urls.pyfrom django.conf.urls import patterns, include, urlfrom django.contrib import adminadmin.autodiscover()from disk import views as disk_viewsurlpatterns = patterns(‘‘, # Examples: # url(r‘^$‘, ‘mysite2.views.home‘, name=‘home‘), # url(r‘^blog/‘, include(‘blog.urls‘)), url(r‘^admin/‘, include(admin.site.urls)), url(r‘^upload/$‘, disk_views.upload),)
啟動服務
在mysite檔案夾下,終端命令列輸入: python manage.py runserver 80
在使用者正確地上傳了檔案後,我們可以在mysite\disk\upload檔案夾下看到此檔案,這個是在models.py裡定義的,讀者們可以試一下。
django 搭建上傳檔案系統——細說Form Validation(二)