iT邦幫忙

2022 iThome 鐵人賽

DAY 26
0

前言

來到第26天,其實還有很多想探討的,不過因為目標是訂在完成一個網站,所以會在後面盡量濃縮一些比較重要的重點
那今天來講一下Django中特別的功能-Django Form
它讓我們能在Django內使用form時更快速 更好用

Form

我們可以使用HTML的Form 來讓用戶端(Client)傳送資料到Django的後台,並讓Django可以在後台操作這些資料。

<form action="" method="POST/GET"></form>

然而要用傳送資料到Django需要大量的工作來建置這些表單,特別是當我們想要延遲連接這些輸入到Models時。
因此就有了Django Form,在Django裡面表示也非常簡單,就是我們熟知的{{form}}
他讓我們可以快速的開發forms,只需要專注開發Django和Python,且增加網站Code的可讀性。

Get & Post

在開始之前要來聊聊Get和Post,如果有稍微寫過網頁,可能都會知道這兩個東西。Get和Post是用來處理form的HTTP方法,他們兩個都是一種http的請求(request),但普遍來說Get常被當作請求(request)資訊和Post則常被當作傳送(send)資訊,這是因為
簡單來說:

  • Get:會將你傳遞的資料和URL包裝再一起成為一個URL,傳送到你的後台,你表單的資料會出現在URL裡面。
  • Post:會將你傳遞的資料封裝好放在message-body,並進行編碼,再傳送到你的後台,你表單的資料不會出現在URL裡面。

有發現問題了嘛!?
使用Get時,你的表單資料會形成URL,如果傳送一些比較重要的密碼等資料,就會很容易洩漏。
因此Get和Post通常會被使用在不同的目的。如:Post適合使用在會更動到資料庫的資料時的請求。Get則是適合用在不會影響到系統時的請求。

那你這時候一定會有個問題,為什麼Get會洩漏資料還要使用呢?
因為使用Get的話可以可以重新載入或按上一頁並不會有任何問題,傳遞的資料會被儲存在瀏覽器的歷史紀錄中,也可以被加到瀏覽器書籤裡面。

Post則相反,重新載入或按上一頁瀏覽器會出現將重新提交資料的提示,因此在方便性上,若沒有安全疑慮就可以使用Get。而在Django form主要使用的是POST的方法。

Django Form

要建立Django Form我們首先我們要在Django_app裡面新建一個form.py

https://ithelp.ithome.com.tw/upload/images/20221006/20150927uZdaPqRdjl.png

forms.py

裡面的寫法就像我們在資料庫設定欄位一樣

from django import forms

class ProductBuyForm(forms.Form):
    Buyer_name = forms.CharField(label="購買者姓名", max_length=20)
    Buyer_email = forms.EmailField(label="購買者信箱")
    Product_name = forms.CharField(label= "產品名稱", max_length= 100)
    Order_num = forms.IntegerField(label="購買數量")

views.py

在views裡面 我們定義一個product_buy
並對請求的方式進行判斷,若是POST則去建立一個ProductBuyForm的實例
並判斷所回傳的資料是否合法
若沒問題就將重新導向到訂單完成畫面
若請求的方式不是POST的話就會返回一個空的表單

在Django form裡 我們可以用:

  • is_valid() :判斷form是否合法
  • form.cleaned_data: 來獲取合法的form,他會以字典的方式呈現。
def product_buy(request):
    if request.method == 'POST':
        form = ProductBuyForm(request.POST)
        if form.is_valid():
            return redirect(reverse("app:order_finish"))
    else:
        form = ProductBuyForm()
    return render(request, 'Django_app/Product_buy.html', context = {'form':form})

def order_finish(request):
    return render(request, 'Django_app/order_finish.html')

接著我們到Template裏面建立一個新的html,名為Product_buy

Product_buy.html

在html 裡面我們先建立一個form
接著我們就可以將我們所建立的form傳送過來

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <h1> How to order Product </h1>
    <form  method = "post">
        {% csrf_token %}
        {{form}}
        <input type = "submit" value="OK">
    </form>
</body>
</html>

呈現畫面

https://ithelp.ithome.com.tw/upload/images/20221008/20150927pTKvBKVzRQ.png

submit 畫面

https://ithelp.ithome.com.tw/upload/images/20221008/20150927MMTXYYY6de.png

參考資料&推薦閱讀

https://docs.djangoproject.com/en/4.1/topics/forms/
https://medium.com/kurt/%E7%B6%B2%E9%A0%81get-%E8%88%87-post-%E5%B7%AE%E7%95%B0-%E7%A7%91%E6%99%AE%E5%A3%B9%E9%BB%9E%E9%80%9A-94cbaa666fdb
https://totoroliu.medium.com/http-post-%E5%92%8C-get-%E5%B7%AE%E7%95%B0-928829d29914


上一篇
Day-25 - admin 管理 - Django 最方便快速的後台
下一篇
Day- 27 - ModelForm - 實現 Django Form 和 Model 的連結
系列文
從0 到 50 初探 如何使用Django 架構出一個網站30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

1 則留言

0
rtfgvb74125
iT邦新手 4 級 ‧ 2022-12-05 11:05:11

您好,我想跟您請問order_finish是另外再創的html嗎?
另外我要怎麼讓html知道我傳出去的參數是要給product_buy接收的

Yusinz iT邦新手 4 級 ‧ 2022-12-07 17:10:46 檢舉

對喔 order_finish有另外創 前面幾篇有提到
另外傳送的部分 是透過建立form來傳遞的

form = ProductBuyForm(request.POST)
if form.is_valid():
    return redirect(reverse("app:order_finish"))

我要留言

立即登入留言