django 搭建上傳檔案系統——細說Form Validation(二)

來源:互聯網
上載者:User

標籤:同步資料   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_tostorage‘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(二)

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.