016---Django的ModelForm
对于forms组件虽然可以帮我们渲染html页面,也可以做校验,但是,保存到数据库要取各字段的值,还要手动保存。所以引入了一个新的组件
这是一个神奇的组件,通过名字我们可以看出来,这个组件的功能就是把model和form组合起来,先来一个简单的例子来看一下这个东西怎么用:比如我们的数据库中有这样一张学生表,字段有姓名,年龄,爱好,邮箱,电话,住址,注册时间等等一大堆信息,现在让你写一个创建学生的页面,你的后台应该怎么写呢?首先我们会在前端一个一个罗列出这些字段,让用户去填写,然后我们从后天一个一个接收用户的输入,创建一个新的学生对象,保存其实,重点不是这些,而是合法性验证,我们需要在前端判断用户输入是否合法,比如姓名必须在多少字符以内,电话号码必须是多少位的数字,邮箱必须是邮箱的格式这些当然可以一点一点手动写限制,各种判断,这毫无问题,除了麻烦我们现在有个更优雅(以后在Python相关的内容里,要多用“优雅”这个词,并且养成习惯)的方法:ModelForm先来简单的,生硬的把它用上,再来加验证条件。
下面是两个是使用示例:
#首先导入ModelForm from django.forms import ModelForm #在视图函数中,定义一个类,比如就叫StudentList,这个类要继承ModelForm,在这个类中再写一个原类Meta(规定写法,并注意首字母是大写的) #在这个原类中,有以下属性(部分): class StudentList(ModelForm): class Meta: model =Student #对应的Model中的类 fields = "__all__" #字段,如果是__all__,就是表示列出所有的字段 exclude = None #排除的字段
#error_messages用法: error_messages = { 'name':{'required':"用户名不能为空",}, 'age':{'required':"年龄不能为空",}, }
#widgets用法,比如把输入用户名的input框给为Textarea #首先得导入模块 from django.forms import widgets as wid #因为重名,所以起个别名 widgets = { "name":wid.Textarea(attrs={"class":"c1"}) #还可以自定义属性 }
#labels,自定义在前端显示的名字 labels= { "name":"用户名" }
1 from django import forms 2 from django.forms import widgets as wid 3 from django.core.exceptions import ValidationError 4 from crm.models import UserProfile 5 6 7 class UserForm(forms.ModelForm): 8 re_password = forms.CharField( 9 max_length=16, label='确认密码', 10 widget=wid.PasswordInput(attrs={"class": "form-control"}), 11 error_messages={ 12 'required': '确认密码不能为空' 13 } 14 ) 15 16 class Meta: 17 model = UserProfile 18 # fields = '__all__' 19 fields = ['username', 'password', 're_password', 'name', 'mobile', 'department'] 20 widgets = { 21 "username": wid.EmailInput(attrs={"class": "form-control"}), 22 "password": wid.PasswordInput(attrs={"class": "form-control"}), 23 } 24 labels = { 25 'username': "用户名", 26 'password': "密码", 27 'department': "所属部门", 28 } 29 error_messages = { 30 'password': { 31 'required': '密码不能为空' 32 }, 33 'username': { 34 'required': '用户名不能为空' 35 } 36 } 37 38 def __init__(self, *args, **kwargs): 39 super().__init__(*args, **kwargs) 40 for field in self.fields.values(): 41 field.widget.attrs.update({"class": "form-control"}) 42 43 def clean(self): 44 pwd = self.cleaned_data.get('password') 45 re_pwd = self.cleaned_data.get('re_password') 46 47 if pwd and re_pwd: 48 if pwd != re_pwd: 49 self.add_error('re_password', '两次密码输入不一致') 50 raise ValidationError('两次密码输入不一致') 51 return self.cleaned_data