Django(七)表單與模型

????表單的作用是實現網頁上的數據交互,用戶在網站輸入數據信息,提交到網站服務器進行處理。用戶表單是web開發的一項基本操作,Django的表單功能有Form類實現,主要分為兩種:django.forms.Form和django.forms.ModelForm。前者是一個基礎的表單。后者是在前者的基礎結果模型所生成的數據表單。


基礎表單

? ? 傳統表單生成方式是在模板文件中編寫HTML代碼實現,在HTML語言中,表單由<form>標簽實現。表單生成方式如下:

<!DOCTYPE html>

<html>

<body>

? ? <form action="" method="post">

? ????? First name:<br>

????????<input type="text" name="firstname" value="Mickey"><br>

????????Last name:<br>

????????<input type="text" name="lastname" value="Mouse">

????????<input type="submit" value="Submit">

????</form>

</body>

</html>

一個完整的表單有4個主要組成部分:提交地址、請求方式、元素控件、提交按鈕。說明如下:

1.提交地址用于設置用戶提交的表單數據應由那個URL來接受和處理,控件<form>的屬性action決定。當用戶想服務器提交數據時,若屬性action為空,則調教的數據應由當前的URL來接受和處理。否則網頁會跳轉到屬性action所指向的URL地址。

2.請求方式用于設置表單的提交方式,通常是get請求或post請求,由控件<form>的屬性method決定。

3.元素控件是提供用戶輸入數據信息的輸入框。由HTML的<input>控件實現,其控件屬性type用于設置輸入框的類型,常用的輸入框類型有文本框、下拉框、復選框

4.提交按鈕提供用戶提交數據到服務器,按鈕也由HTML的<input>控件實現,但該按鈕具有一定的特殊性,因此不歸納到元素空間的 范圍內。


? ? 在模板文件中,直接編寫表單是一種較為簡單的實現方式,如果過表單元素較多,會在無形之中增加模板的代碼量,這樣對日后的維護和更新帶來不便。為了簡化表單的實現過程和提高表單的靈活性,Django提供了完善的表單功能。

? ? 在項目的index中添加空白文件form.py,改文件主要用于編寫表單的實現功能。文件夾可自行命名:同事在文件夾templates中添加模板文件data_form.html,改文件用于將表單的數據顯示到網頁上。最后在文件form.py, views.py, data_form.html添加一下代碼:

# form.py代碼,定義ProductForm表單對象

from django import forms

from .models import *

class ProductForm(forms.Form):

????name = forms.CharField(max_length=20, label='名字',)

????weight = forms.CharField(max_length=50, label='重量')

????size = forms.CharField(max_length=50, label='尺寸')

????choices_list = [(i+1, v['type_name']) for i,v in enumerate(Type.objects.values('type_name'))]

????type = forms.ChoiceField(choices=choices_list, label='產品類型')

# views.py 代碼 將表單 ProductForm實例化并將其傳遞到末班中生成網頁內容

from django.shortcuts import render

from .form import *

def index(request):

????product = ProductForm()

????return render(request, 'data_form.html',locals())

# data_form.html代碼, 將表單對象的內容顯示在網頁上

<!DOCTYPE html>

<html lang="en">

<head>

????<meta charset="UTF-8">

????<title>Title</title>

</head>

<body>

{% if product.errors %}

????<p> 數據出錯啦,錯誤信息:{{ product.errors }}. </p>

????{% else %}

????<form action="" method="post">

????????{% csrf_token %}

????????<table> {{ product.as_table }} </table>

????????<input type="submit" value="提交">

????????{{ product.type.type }}

????????</form>

????????{% endif %}

</body>

</html>

? ? 上述代碼演示了Django內置表單功能的使用方法,主要由form.py,views.py,data_form.html共同實現,說明如下:

? ? 1.在form.py中定義表單ProductForm,表單以類的形式表示,在表單中定義了不同類型的雷屬性,這些屬性在表單中稱為表單字段,每個表單字段代表HTML里面的一個控件,這是表單的基本組成單位。

????2.在views.py中導入form.py所定義的ProductForm類,在視圖函數index中對ProductForm實例化生成對象product,再講對象product傳遞給模板data_form.html

????3.模板data_form.html將對象product以HTML的<table>的形式展示在網頁上。


表單定義

? ? Django的表單功能主要是通過定義表單類,再由類的實例化生成HTML的表單元素控件,這樣可以在模板中減少HTML的硬編碼每個HTML的表單元素控件由表單字段來決定,代碼如下:

# 表單類ProductForm的表單字段name

name = forms.CharField(max_leng=20, label='名稱',)

# 表單字段name所生成的HTML元素控件

<tr>

<th><label for="id_name"> 名稱:</label><th>

<td><input type="text" name="name" id="id_name" required maxlength="20"></td>

</tr>

? ? 從表單字段轉換HTML元素控件可以發現:

? ? 1.字段那么的參數label將轉化成HTML的標簽<label>

????2.字段name的forms.CharField 類型轉換成HTML的<input type="text"> 控件,標簽<input>是一個輸入框控件,type="text"代表當前輸入框為文本輸入框,參數type用于設置輸入框的類型。

????3.字段那么的命名轉換成<input>控件的參數name, 表單字段的參數max_length將轉換成<input>控件的參數required maxlength.

除了上述表單字段外,Django還提供多種內置的表單字段,如需要了解可去官網查詢相關資料。


模型與表單

? ? 數據表單是將模型的字段轉換成表單的字段,再從表單的字段生成HTML的元素控件,這是日常開發中常用的表單之一。接下來重點說明ModelForm實現表單數據與模型數據之間的交互開發。

? ? 首先在文件form.py中定義表單ProductModelForm,該表單繼承自父類forms.ModelForm。代碼如下:

from django import forms

from .models import *

from django.core.exceptions import ValidationError

class ProductModelForm(forms.ModelForm):

????# 添加模型外的表單字段

????productId = forms.CharField(max_length=20, label='產品序號', initial='NO1')

????# 模型與表單設置

????class Meta:

????????# 綁定模型

????????model = Product

????????# fields 屬性是設置轉換字段,'__all__'是將全部模型字段轉換成表單字段

????????# fields = '__all__'

????????fields = ['name','weight','size','type']

????????# exclude是禁止模型字段轉換表單字段

????????exclude = []

????????# labels設置HTML元素控件的label標簽

????????abels = { 'name': '產品名稱', 'weight': '重量', 'size': '尺寸', 'type': '產品類型' }

????????# 定義widgets,設置表單字段的CSS樣式

????????widgets = { 'name': forms.widgets.TextInput(attrs={'class': 'c1'}), }

????????# 定義字段的類型,一般情況下模型的字段會自動轉換成表單字段

????????field_classes = { 'name': forms.CharField }

????????# 幫助提示信息 help_texts = { 'name': '' }

????????# 自定義錯誤信息

????????error_messages = {

????????????????????????????????????????# __all__設置全部錯誤信息

????????????????????????????????????????'__all__':{'required': '請輸入內容', 'invalid': '請檢查輸入內容'},

????????????????????????????????????????# 設置某個字段錯誤信息

????????????????????????????????????????'weight': {'required': '請輸入重量數值', 'invalid': '請檢查數值是否正確'} }

# 自定義表單字段weight的數據清洗

def clean_weight(self):

????# 獲取字段weight的值

????data = self.cleaned_data['weight']

????return data+'g'

? ? 上述代碼中,表單類ProdectModelForm可分為三大部分:添加模型外的表單字段、模型與表單設置和自定義表單字段weight的數據清洗函數,說明如下:

? ? 1.添加模型外的表單字段是在模型已有的字段下添加額外的表單字段。

? ? 2.模型與表單設置是將模型的字段轉換成表單字段,由類meta的屬性實現兩者的字段轉換。

? ? 3.自定義表單字段weight的數據清洗函數只適用于字段weight的數據清洗。


類Meta的屬性及說明

? ? 模型字段轉換成表單字段主要在類Meta中實現。

model:? 必需屬性,用于綁定Model對象。

fields:? ?必需屬性,設置模型內那些字段轉換成表單字段。屬性值為'__all__'代表整個模型的字段,若設置一個或多個,使用列表或元組的數 據格式表示,列表或元組里的元素是模型的字段名。

exclude:? 可選屬性,與fields相反。

labels:? 可選屬性,設置表單字段里的參數label。屬性值以字典表示,字典里ID鍵是模型的字段。

widgets:可選屬性,設置表單字段的參數widget

field_classes:? 可選屬性,將模型的字段重新定義為表單字段類型,默認情況下,模型字段類型會自動轉換為表單字段類型。

help_texts:? 可選屬性,設置表單字段里的參數help_text.

error_messages:? 可選屬性,設置表單字段里的參數error_messages.


重寫初始化函數__init__()

class ProductModelForm(forms.ModelForm):

# 重寫ProductModelForm類的初始函數__init__

????def __init__(self, *args, **kwargs):

????????super(ProductModelForm, self).__init__(*args, **kwargs)

????????# 設置下拉框的數據

????????type_obj = Type.objects.values('type_name')

????????choices_list = [(i + 1, v['type_name']) for i, v in enumerate(type_obj)]

????????self.fields['type'].choices = choices_list

????????# 初始化字段name

????????self.fields['name'].initial = '我的手機'

?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容