最近在學習Django,官方文檔介紹地十分詳細。可是「大而全」就不免會有些不夠速成,和咱們這個浮躁的互聯網時代格格不入,因此我就整理了這個文檔。就像coolshell說的,一泡屎的時間就能夠看完。css
框架的好處就是,它已經爲用戶處理了絕大多數的場景中的重複代碼,提供了封裝好的接口,使得咱們在開發中十分方便。在web開發中,咱們經常遇到的一個場景就是:頁面發起一個請求,後端執行相應的處理(修改數據、查詢數據、插入數據等操做),再予以返回。html
對於這些場景,Django提供了幾個class-based view來處理:python
ListViewweb
UpdateViewshell
CreateView數據庫
DeleteViewdjango
這幾個類視圖分別對應着查詢ListView、更新UpdateView、建立CreateView、刪除DeleteView這幾個操做。在總體上就能夠分爲查看、修改兩個類型。下面,咱們來經過一個例子來展示一下這幾個View怎麼使用。假設咱們須要實現一個用於ssh驗證的web服務。用戶經過頁面能夠新建、查看、修改用於ssh登錄驗證的內容(user、port、password、key)。bootstrap
既然是數據驅動的WEB,首先就必需要有數據。
針對於咱們的需求,數據庫設計以下:segmentfault
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能夠經過你給出的model以及想要展現的model中的field,在對應的數據庫中查詢出對應的對象存放在List對象中,並傳遞給template渲染。這個view只實現了get方法,它只接受get請求。也符合它用於查看數據的需求。在代碼中,咱們只須要指定它對應的模板,對應的model就能夠了。
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這個文件。
from django.conf.urls import patterns, url from .view import SSHAuthListView urlpatterns = patterns('', url(r'^sshAuth/$', SSHAuthListView.as_view(), name='listSSHAuth'),
<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來的請求,數據合法性校驗,並更新數據庫
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。
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表單具備自定義的屬性了:
class SSHAuthCreateView(CreateView): template_name = 'app_name/ssh_create.html' form_class = SSHAuthBootstrapForm success_url = reverse_lazy('app_name:listSSHAuth')
url(r'^sshAuth/createItem/$', SSHAuthCreateView.as_view(), name='createSSHAuth'),
<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>
生成的html代碼以下:
<form role="form" method="post" enctype="multipart/form-data" action="/app_name/createItem"> <input type='hidden' name='csrfmiddlewaretoken' value='*****' /> <div class="form-group"> <label for="id_name">Name:</label> <input class="form-control" id="id_name" maxlength="50" name="name" type="text" /> </div> <div class="form-group"> <label for="id_password">Password:</label> <input class="form-control" id="id_password" maxlength="50" name="password" type="text" /> </div> <div class="form-group"> <label for="id_privateKey">PrivateKey:</label> <input class="form-control" id="id_privateKey" name="privateKey" type="file" /> </div> <div class="form-group"> <label for="id_user">User:</label> <input class="form-control" id="id_user" maxlength="30" name="user" type="text" /> </div> <div class="form-group"> <label for="id_port">Port:</label> <input class="form-control" id="id_port" name="port" type="text" /> </div> <button type="submit" class="btn btn-primary">Create</button> </form>
在渲染的時候,Django已經自動根據model、form_class自動處理了form的全部字段。包括type name id maxlength等屬性。
剩下的UpdateView以及DeleteView與CreateView的實現也是相相似的原理。須要注意的就是在view代碼中,即便是指定了form_class字段,並且form_class中也有指定model,可是仍是須要在view代碼裏給出model。具體實現再也不贅述。