<玩转Django2.0>读书笔记:表单

1. 表单字段

参考:

官方文档

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标签
  • 将表单生成HTML的p标签
  • 生成单个HTML元素控件
  • 获取表单字段的参数label属性值

3. 表单插件weiget

参考:

官方文档

django中widget小部件

4. 表单代码示例(forms.ModelForm)

forms.ModelForm是在forms.Form基础上结合模型所生成的数据表单.数据表单是将模型的字段转换成表单的字段,再从表单生成HTML的元素控件,这是日常开发中常用的表单之一

# 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,在表单中对应的表单字段为ModelChoiceFieldModelMultipleChoiceField

  • 在自定义数据清洗函数时,必须以"clean_字段名"的格式作为函数名,而且函数必须有return返回值

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

posted @ 2019-03-18 01:50  汪小鹏boy  阅读(286)  评论(0编辑  收藏  举报