Django——forms组件
forms组件:通过后端在Django中定义forms类,可以在 html 中动态的生成一个表单;检验用户提交的数据。
在应用中创建一个名为 :forms 的py文件
# 导入 forms 组件 from django import forms # 自定义 forms 表单类 , 表单类必须继承 forms.Form # 在 Django 的 forms 组件中没有提供按钮标签 class MyForm(forms.Form): # 定义表单标签属性 # 在定义之后 , 渲染到 html 中是一个 label 和 input 标签 username = forms.CharField(label='用户名') password = forms.CharField(label='密码')
def showforms(request): # 渲染表单:生成一个表单类对象 , 提交到 html 中 if request.method == 'GET': # 生成一个空白的表单类对象 forms = MyForm() else: # 但请求为 post 请求的时候 , 说明用户提交数据 # 将数据传递该 form 组件(表单类接收的数据要是字典类型的数据) forms = MyForm(request.POST) res = '数据已提交' return render(request , 'index.html' , locals())
<body> <form method="post"> {% csrf_token %} {{ forms }} <input type="submit" value="注册"> </form> <span>{{ res }}</span> </body>
在模板中渲染自定义表单类
<form method="post"> {% csrf_token %} <p>使用表格的样式渲染</p> {{ forms.as_table }} <p>使用段落的样式渲染</p> {{ forms.as_p }} <p>使用列表的样式渲染</p> {{ forms.as_ul }} <input type="submit" value="注册"> </form>
forms 组件提供的组件设置
# 自定义 forms 表单类 , 表单类必须继承 forms.Form # 在 Django 的 forms 组件中没有提供按钮标签 class MyForm(forms.Form): # 定义表单标签属性 # 在定义之后 , 渲染到 html 中是一个 label 和 input 标签 username = forms.CharField(label='用户名') password = forms.CharField(label='密码', # 设置 password 文本框 widget = forms.PasswordInput(), ) # 邮箱 email = forms.EmailField(label='邮箱') # 日期 day = forms.DateField(label='日期', # 设置日历选项 widget=forms.TextInput(attrs={'type':'date'})) # 选项框 # choices 设置选项内容 , 内容要以元组类型设置 gender = forms.ChoiceField(choices=((1,'女'),(2,'男'),(3,'未知')) , label='性别', # 设置选项框类型: 单选 RadioSelect widget=forms.RadioSelect(), # 设置默认选项 initial = 3) work = forms.ChoiceField(choices=((1,'学生'),(2,'搬砖'),(3,'退休')) , label='职业', # 设置选项框类型: 单选 Select widget=forms.Select(), # 设置默认选项 initial = 3) hobby = forms.ChoiceField(choices=((1,'爬山'),(2,'唱歌'),(3,'跳舞'), (4,'rap'),(5,'跆拳道'),(6,'篮球')) , label='爱好', # 设置选项框类型: 多选 CheckboxSelectMultiple widget=forms.CheckboxSelectMultiple(), # 设置默认选项 initial = [2,6]) subject = forms.MultipleChoiceField(choices=((1,'物理'),(2,'化学'),(3,'生物'), (4,'地理'),(5,'历史'),(6,'政治')) , label='科目', # 设置选项框类型: 多选 CheckboxSelectMultiple widget=forms.CheckboxSelectMultiple(), # 设置默认选项 initial = [1]) xy = forms.CharField(label='阿宸要你写代码的协议',widget=forms.CheckboxInput())
forms 组件验证数据
class RegisterView(View): def get(self , request): return render(request , 'register.html') def post(self , request): # 数据给 forms 组件进行数据校验 register_form = RegisterForm(request.POST) # 判断数据是否合法 # is_valid 判断表单类中获取的数据校验是否合法,合法返回 True # register_form.errors 存放的就是数据的错误信息 if register_form.is_valid(): return HttpResponse('注册成功') else: return render(request , 'register.html' , locals())
# 数据验证 class RegisterForm(forms.Form): username = forms.CharField(max_length=10 , min_length=3, # 设置错误信息字典 error_messages={ 'max_length' : '用户名长度超出', 'min_length' : '用户名长度不足', 'required' : '不允许为空' }) password = forms.CharField(max_length=15 , min_length=6, error_messages={ 'max_length': '密码长度超出', 'min_length': '密码长度不足', 'required': '不允许为空' }) password2 = forms.CharField(max_length=15 , min_length=6, error_messages={ 'max_length': '密码长度超出', 'min_length': '密码长度不足', 'required': '不允许为空' }) # 验证数据使用钩子函数 , 钩子:自定义的校验规则 # 局部钩子:给一个字段数据校验 # 定义局部钩子的函数名称:clean_属性名 def clean_username(self): # 勾取数据:获取到对应的属性数据 data = self.cleaned_data.get('username') # 进行数据检验 if not re.match(r'^[a-zA-Z0-9]{3,10}$' , data): # 添加异常信息 # self.add_error(属性 , 错误信息) self.add_error('username' , '用户名不合法') # 把勾取到的数据返回回去 return data # 全局钩子:过多个字段校验 def clean(self): pwd1 = self.cleaned_data.get('password') pwd2 = self.cleaned_data.get('password2') if pwd1 != pwd2: self.add_error('password2', '两次密码不一致') return self.cleaned_data
<body> {# novalidate 关闭浏览器自动渲染 form 组件的错误信息 #} <form method="post" novalidate> {% csrf_token %} <p>用户名:<input type="text" name="username"></p> <span style="color:red;">{{ register_form.username.errors.0 }}</span> <p>密码:<input type="password" name="password"></p> <span style="color:red;">{{ register_form.password.errors.0 }}</span> <p>确认密码:<input type="password" name="password2"></p> <span style="color:red;">{{ register_form.password2.errors.0 }}</span> <input type="submit" value="注册"> </form> </body>