昨天設定完 employer-list
,現在我們把 CURD
中的 C
完成,顧名思義就是 創造 - 新增
的意思,我們要在畫面上新增一個表單,讓使用者可以直接用這個表單新增一個老闆的資料
<!-- 老闆列表頁 -->
http://127.0.0.1:8000/online/employer/create/
url 路徑設定
# online/urls.py
urlpatterns += [
path("employer/create/", views.EmployerCreate.as_view(), name="employer-create")
]
這邊比較特別的是 EmployerCreate
,不過他跟 EmployerListView
一樣,都是等等會在 views.py
檔案新增的 類別 class
路徑設定好了,接下來當然是收發 request/response
的 views.py
檔案:
# online/views.py
# ... 省略
from django.views.generic.edit import CreateView, UpdateView, DeleteView
from django.urls import reverse_lazy
# create
class EmployerCreate(CreateView):
model = Employer
fields = '__all__'
success_url = reverse_lazy('employer-list')
這邊多了兩個新東西,來解釋一下他們分別的作用:
還記得在新增 model
時有設定幾個欄位嗎?以 Employer
為例就是 first_name
、last_name
、age
,而當我們用了這個 fields變數
,就可以控制在 表單新增 Employer
的時候,要設定哪些欄位。
目前這個寫法 fields = '__all__'
就是全部欄位都要出現的意思。
另外一種寫法是像這樣: fields = ['first_name','last_name']
,一次只顯示兩個欄位。
Ps. 不懂的話沒關係,等等會有實際案例
這段的意思是,當你成功新增物件時(也就是當你填好欄位,按下新增按鈕時),會重導到指定的頁面,現在我們這樣設定,當我們新增完,會回到 name = employer-list
的頁面,也就是 http://127.0.0.1:8000/online/employers/
再來就是畫面的地方了,Create 的 templates
比較特別,先照著以下步驟做,等等再解釋:
新增表單的 templates -> EmployerCreate
對應的 templates 路徑是 store/online/templates/online/employer_form.html
有沒有發現,跟前面的 employer_list
比起來,create 的 templates 不是 employer_create
而是 employer_form.html
,這個檔案是 create
和 update
共用的,之後提到 update
時會解釋更清楚
這個寫法跟 ROR 蠻像的,因為 ROR 也可以把 create 和 edit 頁面,用 _form 檔案一起呈現
<!-- store/online/templates/online/employer_form.html -->
{% extends 'sidebar.html' %}
{% block content %}
<h2>{% if request.resolver_match.url_name == 'employer-create' %}新增{% else %}編輯{% endif %} Employer</h2>
<form method="post">
{% csrf_token %}
{{ form.as_p }}
<button type="submit">儲存</button>
</form>
<a href="{% url 'employer-list' %}">返回列表</a>
{% endblock %}
來介紹一下這一段在幹嘛:
url 是 employer-create
,那就顯示 新增
文字,如果不是的話就是顯示 編輯
文字post
{{ form.as_p }}
會將表單的每個欄位以段落 <p> 標籤
的形式呈現我們來看一下現在畫面長麼樣子,瀏覽器輸入剛剛 urls.py 設定好的路徑 http://127.0.0.1:8000/online/employer/create/
:
可以在圖上發現幾個重點:
http://127.0.0.1:8000/online/employer/create/
,確實是渲染我剛剛創建的 employer_form.html
templates 畫面class EmployerCreate
那邊是這樣寫: fields = '__all__'
{{ form.as_p }}
的確有把 Employer 所有欄位,都用 <p>
包起來{% if request.resolver_match.url_name == 'employer-create' %}新增{% else %}編輯{% endif %} Employer
這一段比較難懂,我們下面說明這一段看起來有點複雜,不過沒關係,我們把它印出來看到底是什麼,就不用擔心了,一樣在剛剛 employer_form.html
的頁面底下增加這幾行!
<!-- store/online/templates/online/employer_form.html -->
{% extends 'sidebar.html' %}
{% block content %}
<!-- ...省略 -->
<p>request------ {{ request }}</p>
<p>request.resolver_match------{{ request.resolver_match }}</p>
<p>request.resolver_match.url_name ------ {{ request.resolver_match.url_name }}</p>
{% endblock %}
然後看一下我們網頁目前的截圖:
應該就知道這一段是在幹嘛了,簡單講就是說,到每一個網頁,都會有不同的 request,現在到 http://127.0.0.1:8000/online/employer/create/
路徑的 request 是上面印的那樣,我們利用這個 request 印出我們想要印出的文字,如果今天的 request 不是我們想要的,就印出其他的文字
而現在此頁面的 request-url_name
是 employer-create
,因此我想要印出 新增
這兩個字
Ps. 測試完記得刪掉這些 request文字
喔~
ROR 的表單沒有這麼複雜,因為厲害的 form_with 功能幫你做到很多事情!
前面有提到如果今天這樣設定 fields = ['first_name','last_name']
,就可以修改 form 表單的欄位,現在就來試試看吧,到 views.py 改成下面那樣:
# online/views.py
class EmployerCreate(CreateView):
model = Employer
fields = ['first_name','last_name']
success_url = reverse_lazy('employer-list')
現在的畫面會長這樣,欄位真的剩下指定的兩個!
Ps. 測試完記得改完 fields = '__all__'
最後輸入資料點下儲存後,正常來說應該會成功回到 http://127.0.0.1:8000/online/employers/
這個頁面,原因還記得嗎?是因為當初設定 success_url = reverse_lazy('employer-list')
這一段的原因!
今天學到哪些東西呢?
最後附上 Github: https://github.com/eagle0526/Django-store