07 表单与模型
# 用户表单是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 数据表单的使用