最近在學習Django,官方文件介紹地十分詳細。但是“大而全”就難免會有些不夠速成,和我們這個浮躁的網際網路時代格格不入,所以我就整理了這個文件。就像coolshell說的,一泡屎的時間就可以看完。
框架的好處就是,它已經為使用者處理了絕大多數的場景中的重複程式碼,提供了封裝好的介面,使得我們在開發中十分方便。在web開發中,我們常常遇到的一個場景就是:頁面發起一個請求,後端執行相應的處理(修改資料、查詢資料、插入資料等操作),再予以返回。
對於這些場景,Django提供了幾個class-based view來處理:
- ListView
- UpdateView
- CreateView
- DeleteView
這幾個類檢視分別對應著查詢ListView、更新UpdateView、建立CreateView、刪除DeleteView這幾個操作。在整體上就可以分為檢視、修改兩個型別。下面,我們來通過一個例子來展現一下這幾個View怎麼使用。假設我們需要實現一個用於ssh驗證的web服務。使用者通過頁面可以新建、檢視、修改用於ssh登陸驗證的內容(user、port、password、key)。
Model
既然是資料驅動的WEB,首先就必須要有資料。
針對於我們的需求,資料庫設計如下:
1 2 3 4 5 6 7 8 9 10 11 |
class SSHAuth(models.Model): id = models.AutoField(primary_key=True) name = models.CharField(max_length=50, unique=True) password = models.CharField(max_length=50, blank=True) privateKey = models.FileField(upload_to='sshKey', blank=True) user = models.CharField(max_length=30, blank=True) port = models.IntegerField(blank=True) # python3用__str__ def __unicode__(self): return u'%s' % self.name |
這裡涉及到檔案上傳,想要了解可以參考我的另一篇整理文件。
查詢檢視
ListView
對應官網文件
首先,從最簡單的展示開始。ListView可以通過你給出的model以及想要展示的model中的field,在對應的資料庫中查詢出對應的物件存放在List物件中,並傳遞給template渲染。這個view只實現了get方法,它只接受get請求。也符合它用於檢視資料的需求。在程式碼中,我們只需要指定它對應的模板,對應的model就可以了。
view
1 2 3 4 5 6 7 |
from django.views.generic.edit import CreateView class SSHAuthListView(ListView): template_name = 'app_name/sshauth_list.html' model = SSHAuth |
說明:
上面我沒有給出filed的值,預設就是SSHAuth這個model中的所有filed都將被展示。
其實template_name也可以不特別給出。如果你在Django設定settings.py中的TEMPLATES下配置了‘APP_DIRS’: True 的話,Django預設會去渲染/project/app_name/templates/app_name/sshauth_list.html這個檔案。
url
1 2 3 4 |
from django.conf.urls import patterns, url from .view import SSHAuthListView urlpatterns = patterns('', url(r'^sshAuth/$', SSHAuthListView.as_view(), name='listSSHAuth'), |
template
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 |
<table> <thead> <tr> <th>ID</th> <th>Name</th> <th>Password</th> <th>PrivateKey</th> <th>User</th> <th>Port</th> </tr> </thead> <tbody> {% for item in object_list %} <tr> <td>{{ item.id }}</td> <td>{{ item.name }}</td> <td>{{ item.password }}</td> <td>{{ item.privateKey }}</td> <td>{{ item.user }}</td> <td>{{ item.port }}</td> </tr> {% endfor %} </tbody> </table> |
說明:
模板中的object_list物件就是view從model中取出的資料。以list的型別儲存著所有資料instance。這個’object_list’的變數名是Django預設提供的,也可以人為修改為你想要的變數名,詳細請看官網文件。
修改檢視
接下來就是第二類修改檢視了。在web開發中約定俗成的規則是,對於查詢類的請求用get,對於修改類的請求用post。Django在設計的時候也遵循了這個原則,所以以下的每個view中,都具有支援get和post的函式。
CreateVIew:
- get——根據model提供一個空form
- post——接收從get發來的請求,資料合法性校驗,插入資料庫
UpdateView:
- get——根據model從資料庫取出例項,並渲染form
- post——接收從get來的請求,資料合法性校驗,並更新資料庫
CreateView
view
1 2 3 4 5 |
class SSHAuthCreateView(CreateView): template_name = 'app_name/ssh_create.html' model = SSHAuth success_url = reverse_lazy('app_name:listSSHAuth') |
說明:
model就是對應的資料庫,在get請求傳送過來的時候,Django會根據model裡的欄位個數、型別渲染form。而在post請求傳送過來的時候,Django會根據model裡的field屬性去做合法性校驗(型別是否正確、欄位是否必填等),在校驗成功以後重定向至success_url。
像上面的SSHAuthCreateView直接取model裡面的資料,在password輸入的時候input的type預設取的是text(因為model為CharField)。但是我們想要它是一個password的type。或者你想給它加入class屬性,用於指定css。這樣的話,就要自定製form。可以自己寫一個form_class,然後在CreateView裡面新增這個form_class。
form
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 |
from django import forms from .models import SSHAuth, Inventory bootstrap_form_css_class = {"class": 'form-control'} class SSHAuthBootstrapForm(forms.ModelForm): """ Use Bootstrap css. An abstract base class. """ class Meta: model = SSHAuth fields = ['name', 'password', 'privateKey', 'user', 'port'] # add html class attribute to form's component. widgets = { 'name': forms.TextInput(attrs=bootstrap_form_css_class), 'password': forms.PasswordInput(attrs=bootstrap_form_css_class), 'privateKey': forms.ClearableFileInput(attrs=bootstrap_form_css_class), #ClearableFileInput提供對UpdateView的clear支援 'user': forms.TextInput(attrs=bootstrap_form_css_class), 'port': forms.TextInput(attrs=bootstrap_form_css_class), } |
說明:
fields欄位為想要展示的欄位,因為id是自增的主鍵,所以不做修改。widgets為form的欄位型別以及html屬性。其中的PasswordInput會將form中的該欄位設為password型別;而ClearableFileInput則是帶有清除檔案功能的型別。
這樣,只需要在view當中加入這個form_class就可以實現模板中渲染的form表單具有自定義的屬性了:
1 2 3 4 5 |
class SSHAuthCreateView(CreateView): template_name = 'app_name/ssh_create.html' form_class = SSHAuthBootstrapForm success_url = reverse_lazy('app_name:listSSHAuth') |
url
1 |
url(r'^sshAuth/createItem/$', SSHAuthCreateView.as_view(), name='createSSHAuth'), |
template
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
<form role="form" method="post" enctype="multipart/form-data" action="{% url 'app_name:createSSHAuth' %}"> {% csrf_token %} {% for field in form %} {% if field.errors %} <div class="form-group has-error" > {% else %} <div class="form-group"> {% endif %} {{ field.label_tag }} {{ field }} {% for error in field.errors %} <span class="label label-danger">{{ error }}</span> {% endfor %} </div> {% endfor %} <button type="submit" class="btn btn-primary">{% block btn_name %}{% endblock %}</button> </form> |