<玩轉Django2.0>讀書筆記:表單

1. 表單字段

參考:html

官方文檔git

Django表單字段彙總數據庫

2. 表單代碼示例(forms.Form)

# form.py代碼
# 獲取數據庫數據
choices_list = [(i+1,v['typename']) for i,v in \
    enumerate(ProductType.objects.values('typename'))]

# 自定義數據驗證函數
def price_validate(value):
    if int(value) <= 0:
        print("******已進入驗證******")
        raise ValidationError("請輸入正確價格")

class ProductForm(forms.Form):
    # 設置錯誤信息並設置樣式
    name = forms.CharField(max_length=20,\
        label="名字",\
        # 參數widget是一個forms.widget對象,起做用是是設置表單字段CSS樣式  
        widget=forms.widgets.TextInput(attrs={"class":"c1"}),\
            # 用於數據驗證失敗後的錯誤信息
        error_messages={"required":"名字不能爲空"})

    tttype = forms.ChoiceField(choices=choices_list,\
        label="產品類型",\
        widget = forms.widgets.Select(attrs={"class":"type","size":"4"}))

    price = forms.DecimalField(max_digits=6,\
        decimal_places=2,\
        label="銷售價格",\
        # 自定義數據驗證函數
        validators = [price_validate])
<!-- form.html代碼 -->
{% if product.errors %}
    <p>
        數據出差啦!出錯信息:{{product.errors}}
    </p>
{% else %}
<form action="" method="post">
    {% csrf_token %}
    <table>
        {{product.as_table}}            
    </table>
    <input type="submit" value="提交">
</form>
{% endif %}
# views.py中代碼
def form_views(request):
    if request.method == "GET":
        product = ProductForm()
        return render(request,'form.html',locals())

    else:
        product = ProductForm(request.POST)
        if product.is_valid():
            # 獲取網頁控件name的數據  
            # cleaned_data 將控件的數據進行清洗,轉換成Python數據類型       
            name = product.cleaned_data['name']
            tttype = product.cleaned_data['tttype']
            price = product.cleaned_data['price']
            print('*'*20,name,tttype,price)

            return HttpResponse('提交成功')
        else:
            # 將錯誤信息輸出,error_msg試講錯誤信息以json格式輸出
            error_msg = product.errors.as_json()
            print(error_msg)
            return render(request,"form.html",locals())
  • 將表單生成HTML的ul標籤 {{product.as_ul}}
  • 將表單生成HTML的p標籤 {{product.as_p}}
  • 生成單個HTML元素控件 {{product.type}}
  • 獲取表單字段的參數label屬性值 {{product.type.label}}

3. 表單插件weiget

參考:django

官方文檔json

django中widget小部件函數

4. 表單代碼示例(forms.ModelForm)

forms.ModelForm是在forms.Form基礎上結合模型所生成的數據表單.數據表單是將模型的字段轉換成表單的字段,再從表單生成HTML的元素控件,這是平常開發中經常使用的表單之一post

# forms代碼
from django import forms
from django.core.exceptions import ValidationError
from .models import *

class ProductModelForm(forms.ModelForm):
    # 添加模型外的表單字段
    productId = forms.CharField(max_length=20,label="產品序號")
    # 模型與表單設置
    class Meta:
        # 綁定模型
        model = Product

        # field屬性用於設置轉換字段,'__all__'是將所有模型字段轉換成表單字段
        # fields = "__all__"
        # fields = ["name","tttype","price","weight"]

        # exclude用於禁止模型字段轉換成表單字段
        exclude = ["ttype"]

        # label設置HTML元素控件label標籤
        labels = {
            "name" : "產品名稱",
            "tttype" : "產品類型",
            "price" : "產品價格",
            "weight" : "產品重量"
        }

        # 定義widgets,設置表單字段的CSS樣式
        widgets = {
            "name" : forms.widgets.TextInput(attrs={"class":"c1"}),
            "tttype" : forms.widgets.Select(attrs={"class":"type","size":"4"})
        }

        # 定義字段類型,通常狀況下模型的字段會自動轉換成表單字段
        field_classes = {
            "name" : forms.CharField
        }

        # 幫助提示信息
        help_texts = {
            "price" : "應該大於0"
        }

        # 自定義錯誤信息
        error_texts = {
            # __all__ 設置所有錯誤信息
            "__all__" :{
                "required" : "請輸入內容",
                "invalid" : "請檢查輸入內容"
            },
            # 設置摸個字段的錯誤信息
            "price" : {
                "required" : "請輸入價格",
                "invalid" : "請檢查數值是否正確"
            }
        }

    # 自定義表單字段weight的數據清洗
    def clean_weight(self):
        data = self.clean_data["weight"]
        return data + "g"
  • 模型字段類型爲ForeignKeyManyToManyField,在表單中對應的表單字段爲ModelChoiceFieldModelMultipleChoiceFieldui

  • 在自定義數據清洗函數時,必須以"clean_字段名"的格式做爲函數名,並且函數必須有return返回值spa

def modelform_views(request,id):
    if request.method == "GET":
        instance = Product.objects.filter(id=id).first()
        # 判斷數據是否存在
        if instance:
            product = ProductModelForm(instance=instance)
        else:
            product = ProductModelForm(initial={"name":"mi","price":1999})
        return render(request,'form.html',locals())
    
    else:
        product = ProductModelForm(request.POST)
        if product.is_valid():
            # 獲取weight的數據,並經過clean_weight進行清洗
            weight = product.cleaned_data["weight"]

            # # 數據保存方法一
            # # 直接將數據保存到數據庫
            # product.save()

            # # 數據保存方法二
            # # save方法設置commit=False,將生成數據庫對象product_db,
            # # 而後對該對象的屬性值修改並保存
            # product_db = product.save(commit=False)
            # product_db.name = "new" + product_db.name
            # product_db.save()

            # 數據保存方法三
            # save_m2m()方法用於保存ManyToMany的數據模型
            # product.save_m2m()

            return HttpResponse("提交成功!weight清洗後的數據爲" + weight)

        else:
            # 將錯誤信息輸出,error_msg是將錯誤信息以json格式輸出
            error_msg = product.errors.as_json()
            print('*'*20,error_msg)
            return render(request,'form.html',locals())
  • 表單初始化4種方法插件

    • ProductModelForm(initial={'name':value}),適用於全部表單

    • ProductModelForm(instance=object),只適用於ModelForm

    • 定義表單時,能夠對錶單字段設置初始化參數initial,此方法不適用於ModelForm,如 name=forms.CharField(initial=value)

    • 重寫表單類的初始化函數__init__(),適用於全部表單類, 如在初始化函數__init__()中設置 self.field['name'].inital=value

相關文章
相關標籤/搜索