# 用户表单是Web开发的一项基本功能,Django的表单功能有Form类实现,主要分两种:django.forms.Form和django.forms.ModelForm。
# 前者是一个基础的表单功能,后者是在前者的基础上结合模型生成的数据表单。
7-1 初识表单
# 传统的表单生成方式是在模板文件中编写HTML代码实现,在HTML语言中,表单由<form>标签实现。
# 表单主要有四个组成部分:提交地址、请求方式、元素控件和提交按钮。
# 提交地址:由空间<form>的属性action决定
# 请求方式:由空间<form>的属性method决定
# 元素控件:由HTNL的<input>控件实现
# 提交按钮:该按钮也是由HTML的<input>控件实现的
# form.py代码,定义ProductFrom表单对象
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='产品类型')
# view.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代码,将表单对象的内容显示在网页上
<form action="" method="post">
{% csrf_token %}
<table>
{{ product.as_table }}
</table>
<input type="submit" value="提交">
{{ product.type.type }}
</form>
9-4 表单的定义
# 表7-1 Django内置的表单字段
# BooleanField 复选框,如果字段带有required=True,复选框被勾选上
# CharField 文本框,参数max_length和min_length分别设置输入长度
# ChoiceField 下拉框,参数choices设置数据内容
# 表7-2 表单字段的共同参数
# Required 输入数据是否为空,默认值为True
# Widget 设置HTML控件的样式
# Label 用于生成Label标签或显示内容
# 自定义数据验证函数
# 优化的代码分别使用了参数widget,label,error_messages和validators,这四个参数是实际开发中常用的参数
from django import forms
from .models import *
from django.core.exceptions import ValidationError
def weight_validate(value):
if not str(value).isdigit():
raise ValidationError('请输入正确的重量')
# 表单
class ProductForm(forms.Form):
# 设置错误信息并设置样式
name = forms.CharField(max_length=20, label='名字',
widget=forms.widgets.TextInput(attrs={'class': 'c1'}),
error_messages={'required': '名字不能为空'},)
# 使用自定义数据验证函数
weight = forms.CharField(max_length=50, label='重量',validators=[weight_validate])
size = forms.CharField(max_length=50, label='尺寸')
# 获取数据库数据
choices_list = [(i+1, v['type_name']) for i,v in enumerate(Type.objects.values('type_name'))]
# 设置CSS样式
type = forms.ChoiceField(widget=forms.widgets.Select(attrs={'class': 'type','size':'4'}),
choices=choices_list,label='产品类型')
# views.py代码,对表单提交的数据进行处理
from django.shortcuts import render
from django.http import HttpResponse
from .form import *
def index(request):
# GET请求
if request.method == 'GET':
product = ProductForm()
return render(request, 'data_form.html',locals())
# POST请求
else:
product = ProductForm(request.POST)
if product.is_valid():
# 获取网页控件name的数据
# 方法一
name = product['name']
# 方法二
# cleaned_data将控件name的数据进行清洗,转换成Python数据类型
cname = product.cleaned_data['name']
return HttpResponse('提交成功')
else:
# 将错误信息输出,error_msg是将错误信息以json格式输出
error_msg = product.errors.as_json()
print(error_msg)
return render(request, 'data_form.html', locals())
7-3 模型与表单
# 数据表单是将模型的字段转换成表单的字段,在从表单的字段生成HTML的元素控件
from django import forms
from .models import *
from django.core.exceptions import ValidationError
# 数据库表单
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 = '我的手机'
# 添加模型外的表单字段
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标签
labels = {
'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'
# 表7-3 类Meta的属性及说明
# Model 必备属性,用于绑定Model对象
# Fields
# Exclude
7-4 数据表单的使用