Django 提供 下列四種通用views
- Base views
- Generic display views
- Generic editing views
- Generic date views
Base Views
View
View是所有class-based base的父類別,所有通用view都從此類別繼承。此類別可以從 django.views
import得來
TemplateView
將自定義的模板(Template)呈現出來,並且可以包含Model的query
RedirectView
重新導向至指定的URL。
在指定的URL中,也可以包含Python的字典風格的字串格式(Dictionary-style string formatting),所以在RedirectView中,就可以由URL中輸入的字串重新導向到不同的位置,或是呈現不同的內容。
Generic display views
Django 提供兩種呈現資料的通用views,這兩種呈現資料的view是一般在網頁開發中最常遇到的。
DetailView
當DetailView被執行時,self.object
將會包含View正在操作的物件。
例如:
- 將前面所使用的Coffee model利用 DetailView來呈現,首先,先在model內新增一個SlugField
*** models.py ***
from django.db import modelsclass Coffee(models.Model):
name = models.CharField(max_length=60)
price = models.IntegerField()
slug = models.SlugField(max_length=40)
- 在
views.py
只需要兩行程式碼即可完成:
*** views.py ***
from django.views.generic.detail import DetailView
from mycafe.models import Coffeeclass CoffeeDetailView(DetailView):
model = Coffee
- URL部分,只需要將對應slug的正規輸入法寫好,即可讀取指定Model中的項目。如下:
*** urls.py ***
from django.conf.urls import url, include
from .views import CoffeeDetailViewurlpatterns = [
url(r'^detail/(?P<slug>[-\w]+)/$', CoffeeDetailView.as_view()),
]
- 在Template中只要利用
{{object.field_name}}
即可讀取欄位的資料。需要注意的是,DetailView會去存取templates\[app_name]\[model_name]_detail.html
,所以我們的CoffeeDetailView就會需要建立一個coffee_detail.html
*** coffee_detail.html ***
<h1>Coffee name: {{ object.name }}</h1>
<p>$: {{ object.price }}</p>
ListView
- ListView 是用來呈現資料列表的。
- 當此View被執行時
self.object_list
會包含此View正在執行的物件。
<h1>Coffee</h1>
<ul>
{% for coffee in object_list %}
<li>{{ coffee.name }}, Price: {{ coffee.price }}</li>
{% empty %}
<li>No coffee exists.</li>
{% endfor %}
</ul>
Generic editing views
FormView
- FormView是用來顯示Form的一個View。
- 只要在FormView的class中填入
template_name
、form_class
以及success_url
就可以將Form呈現出。
例如:
*** forms.py ***
class CoffeeForm(forms.ModelForm):
class Meta:
model = Coffee
fields = '__all__'*** views.py ***
from django.views.generic.edit import FormViewclass NewCoffeeView(FormView):
template_name = 'coffee_new.html'
form_class = CoffeeForm
success_url = '/coffee/thanks/'
CreateView
- CreateView是由Model直接建立Form,跟FormView不同的是,不用預先設計ModelForm。
例如:
*** views.py ***
from django.views.generic.edit import CreateViewclass NewCoffeeView2(CreateView):
model = Coffee
field = '__all__'
- CreateView會依照app name以及model name自行去尋找template 檔案。
如上面的例子,Template將會預設在templates/mycafe/coffee_form.html
這個路徑。
UpdateView
- UpdateView可以用來編輯已經存在的資料,用法與CreateView相同,只需要帶入
model
、field
,若Model並未定義get_absolute_url
,則需多加一個success_url
。
例如:
*** views.py ***
from django.views.generic.edit import UpdateViewclass CoffeeUpdateView(UpdateView):
model = Coffee
fields = ['name', 'price']
success_url = '/coffee/thanks/'
DeleteView
- DeleteView顧名思義是將資料刪除的Generic view,當收到request method為
POST
時,則將該資料刪除,若收到GET
則呈現此View。 - 此View目的是提供一個確認的頁面,方便使用者確認刪除。
- DeleteView只需要提供
model
success_url
*** views.py ***
from django.urls import reverse_lazyclass CoffeeDeleteView(DeleteView):
model = Coffee
success_url = reverse_lazy('menu')
- 另外,在使用DeleteView時,預設的Template是
app_name\[model_name]_confirm_delete.html
,
我們以在mycafe app底下的Coffee model為例,我們必須預先準備一個templates\mycafe\coffee_confirm_delete.html
,如下:
*** coffee_confirm_delete.html ***<form action="" method="post">
{% csrf_token %}
<p>Are you sure you want to delete "{{ object.name }}"?</p>
<input type="submit" value="Confirm" />
</form>
Generic date views
- Generic data views 是用來處裡日期相關的資料。
ArchiveIndexView
- ArchiveIndexView是所有Generic Date Views的最上層,直接在URL中使用,如下:
*** urls.py ***
from django.conf.urls import url
from django.views.generic.dates import ArchiveIndexView
from mycafe.models import Coffee
urlpatterns = [
url(r'^archive/$',
ArchiveIndexView.as_view(model=Coffee, date_field="pub_date"), name="coffee_archive"),
]
- 在使用ArchiveIndexView之前,Model必須包含DateField()
*** models.py ***
from django.db import modelsclass Coffee(models.Model):
name = models.CharField(max_length=60)
price = models.IntegerField()
slug = models.SlugField(max_length=40)
pub_date = models.DateField()
YearArchiveView
- YearArchiveView 讓使用者可以在URL中輸入特定的年份,並依據年份搜尋資料,且按照月份排序,預設是不支援未來的資料,若需顯示未來的資料,則將
allow_future
設定為True
即可。 - 例如:
*** views.py ***
class CoffeeYearArchiveView(YearArchiveView):
queryset = Coffee.objects.all()
date_field = "pub_date"
make_object_list = True
allow_empty = True
- 說明: 在ArchiveView中提供需要查詢的
queryset
,以及欄位date_field
,若需要將資料列出來,則將make_object_list
設定為True
;若當資料不存在時,仍然需要處裡,則將allow_empty
設定為True
。 - 同時,template的路徑為:
templates\[app_name]\[model_name]_archive_year.html
- URL的設定如下:
from django.conf.urls import url
from mycafe.views import CoffeeYearArchiveView
urlpatterns = [
url(r'^(?P<year>[0-9]{4})/$', CoffeeYearArchiveView.as_view()),
]
MonthArchiveView
- MonthArchiveView 可以顯示特定月份的所有的資料。
- 使用類似於YearArchiveView
WeekArchiveView
- WeekArchiveView 可以顯示特定周的所有資料。
- 使用類似於YearArchiveView
DayArchiveView
- DayArchiveView 可以顯示特定日期的所有資料。
- 使用類似於YearArchiveView
TodayArchiveView
- TodayArchiveView 可以顯示今日的所有資料。
- 與DayArchiveView完全相同,差別在於會自動帶入今日的日期。
小結
如同文章開始所說,開發網站的時候常常會有很多重複的工作,django的Generic view可以幫我們很大一個忙,節省很多時間在設計基本的項目。
不過Generic View也不是萬能的,畢竟只算是 “通用” 的View,所以有需要自己實做的項目,還是自己來比較實際。