繼 Day25 所提到的 Class-Based Views (CBV),我們知道如何透過 Django 提供的模板來更快速地完成我們想要的網頁,今天我們就再繼續來聊聊 CBV 其他的模板吧!
今天要介紹的有
CreateView
UpdateView
廢話不多說,就讓我們直接進入主題吧 ^^
首先,我們先在 views.py 建立一個 VendorCreateView
:
from django.views.generic import CreateView
class VendorCreateView(CreateView):
# form_class = VendorModelForm
model = Vendor
fields='__all__'
template_name = 'vendors/vendor_create.html'
而我們建立的這一個 View 的方法有兩種 :
model + fields
: 透過 我們所想要使用的 資料 及 資料欄位來建立表格,透過我上面的範例,可以建立如下圖的viewfields
改成fields= ['vendor_name', 'store_name']
相信大家就一目瞭然了吧 ^^
下會附上 model 及 template 程式碼 供大家對照上面的範例
# model - Vendor
class Vendor(models.Model):
vendor_name = models.CharField(max_length = 20) # 攤販的名稱
store_name = models.CharField(max_length = 10) # 攤販店家的名稱
phone_number = models.CharField(max_length = 20) # 攤販的電話號碼
address = models.CharField(max_length = 100) # 攤販的地址
...略
# template - vendor_create.html
{% extends "base.html" %}
{% block title %} My store {% endblock %}
{% block content%}
<h2> Vendor Create</h2>
<form method='POST'>
{% csrf_token %}
{{ form.as_p }}
<input type="submit" value="save" />
</form>
{% endblock %}
還有不要忘記了 urls.py 的設定!
from .views import (
...略
VendorCreateView,
)
app_name = 'vendors'
urlpatterns = [
path('', VendorListView.as_view(), name='index'),
path('<int:pk>/', VendorDetailView.as_view(), name='vendor_id'),
path('create/', VendorCreateView.as_view(), name='create'), # 新增
...略
]
form_class
: 我們也可以透過綁定 ModelForm
的方式來更簡化撰寫的過程更明確的說法是,其實 model 及 fields 這兩者都已經在 ModelForm 就已經撰寫完畢了,等於是你可以直接套用 ModelForm 的格式,這樣子的好處是更方便我們維護
此時我們的程式碼可以修改成這樣,VendorModelForm於下方供大家參考
# CreateView
class VendorCreateView(CreateView):
form_class = VendorModelForm
# model = Vendor
# fields= ['vendor_name', 'store_name']
template_name = 'vendors/vendor_create.html'
# modelForm
class VendorModelForm(forms.ModelForm):
class Meta:
model = Vendor
fields = '__all__'
# fields = (
# 'vendor_name',
# 'store_name',
# 'phone_number',
# 'address',
# )
labels = {
'vendor_name': _('攤販名稱'),
'store_name' : _('店名'),
'phone_number' : _('電話'),
'address' : _('地址'),
}
如此一來,短短的幾行程式碼,就能夠完成我們大部分的事情
然後我們馬上就來新增資料吧! 然後這裡示範一個錯誤給大家了解
在我們資料進行驗證,成功並儲存了之後,你必須要告訴它要轉到哪一個網址,所以在 model 必須定義 get_absolute_url(self)
# model - vendor
def get_absolute_url(self):
return reverse("vendors:vendor_id", kwargs={"id": self.id})
我們再次試著儲存資料
然後就會成功轉到`127.0.0.1/int:pk/去囉 ^^
有了CreateView,要完成一個簡易的 UpdateView 會相當的簡單,我們一樣在 views.py 新增 VendorUpdateView
# from django.views.generic import UpdateView # 新增
class VendorUpdateView(UpdateView):
form_class = VendorModelForm
template_name = 'vendors/vendor_create.html'
queryset = Vendor.objects.all() # 這很重要
之所以要加上 queryset 的原因是因為
UpdateView 會呼叫 get_object()
def get(self, request, *args, **kwargs):
self.object = self.get_object()
return super(BaseUpdateView, self).get(request, *args, **kwargs)
def post(self, request, *args, **kwargs):
self.object = self.get_object()
return super(BaseUpdateView, self).post(request, *args, **kwargs)
但是 CreateView 並不會呼叫 get_object()
def get(self, request, *args, **kwargs):
self.object = None
return super(BaseCreateView, self).get(request, *args, **kwargs)
def post(self, request, *args, **kwargs):
self.object = None
return super(BaseCreateView, self).post(request, *args, **kwargs)
要更了解 Django 內建的類別,就要開始看 Source code,這些都是 one-time pain,有機會就把類別拿起來看吧 ^^
接著再將 urls.py 加入此行即可
from .views import (
...略
VendorUpdateView,
)
app_name = 'vendors'
urlpatterns = [
...略
path('<int:pk>/update/', VendorUpdateView.as_view(), name='update'), # 新增
...略
]
如此一來就能夠修改view囉!
今天延後昨天的議題 CBV,CBV固然方便,但是因為繼承了很多類別,所以想要更深入的了解如何操作,就勢必要去看 Source code囉!
希望今天的內容對你有幫助 ^^ 我們明天見
哪怕路再長,哪怕受再多的傷,哪怕前方有阻擋,也要照亮 From 南西肯恩