iT邦幫忙

2023 iThome 鐵人賽

DAY 10
0
自我挑戰組

Django 初學入門 - 從 ROR 的角度來學習 Django系列 第 10

DAY10 - Employer CRUD 中的 Create

  • 分享至 

  • xImage
  •  

昨天設定完 employer-list,現在我們把 CURD 中的 C 完成,顧名思義就是 創造 - 新增 的意思,我們要在畫面上新增一個表單,讓使用者可以直接用這個表單新增一個老闆的資料

連結

<!-- 老闆列表頁 -->
http://127.0.0.1:8000/online/employer/create/

urls.py

url 路徑設定

# online/urls.py

urlpatterns += [
    path("employer/create/", views.EmployerCreate.as_view(), name="employer-create")
]

這邊比較特別的是 EmployerCreate,不過他跟 EmployerListView 一樣,都是等等會在 views.py 檔案新增的 類別 class

views.py

路徑設定好了,接下來當然是收發 request/responseviews.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') 

這邊多了兩個新東西,來解釋一下他們分別的作用:

fields

還記得在新增 model 時有設定幾個欄位嗎?以 Employer 為例就是 first_namelast_nameage,而當我們用了這個 fields變數,就可以控制在 表單新增 Employer 的時候,要設定哪些欄位。
目前這個寫法 fields = '__all__' 就是全部欄位都要出現的意思。

另外一種寫法是像這樣: fields = ['first_name','last_name'],一次只顯示兩個欄位。

Ps. 不懂的話沒關係,等等會有實際案例

success_url = reverse_lazy('employer-list')

這段的意思是,當你成功新增物件時(也就是當你填好欄位,按下新增按鈕時),會重導到指定的頁面,現在我們這樣設定,當我們新增完,會回到 name = employer-list 的頁面,也就是 http://127.0.0.1:8000/online/employers/

templates

再來就是畫面的地方了,Create 的 templates 比較特別,先照著以下步驟做,等等再解釋:

新增表單的 templates -> EmployerCreate 對應的 templates 路徑是 store/online/templates/online/employer_form.html

有沒有發現,跟前面的 employer_list 比起來,create 的 templates 不是 employer_create 而是 employer_form.html,這個檔案是 createupdate 共用的,之後提到 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 %}

來介紹一下這一段在幹嘛:

  1. 一樣先引入側邊欄
  2. 客製化 content 區塊
  3. 判斷現在的 request,如果 url 是 employer-create,那就顯示 新增 文字,如果不是的話就是顯示 編輯 文字
  4. 新增/編輯表單記得一定要使用 post
  5. 使用 csrf_token 避免資安問題
  6. form.as_p 是一個 Django 中的模板語法,它用於渲染表單(form)的 HTML 內容。在上述模板中,{{ form.as_p }} 會將表單的每個欄位以段落 <p> 標籤 的形式呈現

瀏覽目前畫面

我們來看一下現在畫面長麼樣子,瀏覽器輸入剛剛 urls.py 設定好的路徑 http://127.0.0.1:8000/online/employer/create/

https://ithelp.ithome.com.tw/upload/images/20230921/20162365wGlVoSDFlG.png

可以在圖上發現幾個重點:

  1. 路徑是 http://127.0.0.1:8000/online/employer/create/,確實是渲染我剛剛創建的 employer_form.html templates 畫面
  2. 畫面上渲染出 Employer 所有欄位的原因,是因為我們在 class EmployerCreate 那邊是這樣寫: fields = '__all__'
  3. 我們用 {% csrf_token %} 語法生出的 HTML 欄位,有確實的生成一段亂數碼
  4. 我們用 {{ form.as_p }} 的確有把 Employer 所有欄位,都用 <p> 包起來
  5. {% if request.resolver_match.url_name == 'employer-create' %}新增{% else %}編輯{% endif %} Employer 這一段比較難懂,我們下面說明

request 的差異印出不同文字

這一段看起來有點複雜,不過沒關係,我們把它印出來看到底是什麼,就不用擔心了,一樣在剛剛 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 %}

然後看一下我們網頁目前的截圖:

https://ithelp.ithome.com.tw/upload/images/20230921/20162365SdDXLhNlGm.png

應該就知道這一段是在幹嘛了,簡單講就是說,到每一個網頁,都會有不同的 request,現在到 http://127.0.0.1:8000/online/employer/create/ 路徑的 request 是上面印的那樣,我們利用這個 request 印出我們想要印出的文字,如果今天的 request 不是我們想要的,就印出其他的文字

而現在此頁面的 request-url_nameemployer-create,因此我想要印出 新增 這兩個字

Ps. 測試完記得刪掉這些 request文字 喔~


ROR 的表單沒有這麼複雜,因為厲害的 form_with 功能幫你做到很多事情!


測試 fields = ['first_name','last_name']

前面有提到如果今天這樣設定 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')

現在的畫面會長這樣,欄位真的剩下指定的兩個!

https://ithelp.ithome.com.tw/upload/images/20230921/20162365vuPw8Me3fP.png

Ps. 測試完記得改完 fields = '__all__'

最後輸入資料點下儲存後,正常來說應該會成功回到 http://127.0.0.1:8000/online/employers/ 這個頁面,原因還記得嗎?是因為當初設定 success_url = reverse_lazy('employer-list') 這一段的原因!

總結

今天學到哪些東西呢?

  1. Django 物件 Create 如何設定
  2. Create 表單的各種參數
  3. request 的差異

最後附上 Github: https://github.com/eagle0526/Django-store


上一篇
DAY9 - Employer 老闆列表頁面
下一篇
DAY11 - Employer CRUD 中的 Read
系列文
Django 初學入門 - 從 ROR 的角度來學習 Django30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言