Django笔记–Django的Form组件
这篇文章来记录我学习Django中的Form组件。
之前实现在注册功能的实现中都是使用html中的form表单提交数据,会发现使用起来不够方便。因此,Django提供的Form组件,使用起来会比html中的form表单更加方便。
Django的Form组件的常用的字段参数
字段参数 | 意义 |
---|---|
required=True | 是否可以为空 |
widget=None | HTML插件 |
label | 生成的Label标签中的内容 |
initial=None | 初始值 |
error_messages=None | 错误提示信息 |
validators=[] | 自定义验证规则 |
diasbled=False | 是否支持编辑 |
max_length | 最大长度 |
min_length | 最小长度 |
这里简单的实现注册功能来体现Django的Form组件的使用方法。
附上代码:
视图view.py
#views.py
from django.shortcuts import render, HttpResponse
from registerapp.forms import RegForm
def register(request):
form_obj = RegForm()
if request.method == 'POST':
form_obj = RegForm(request.POST)
if form_obj.is_valid():
#print(form_obj.cleaned_data) #所有匹配成功的数据(字典形式)
return HttpResponse("校验成功")
return render(request, 'register.html', {'form_obj': form_obj})
校验forms.py
#forms.py
from django import forms
from django.forms import widgets
from django.core.validators import RegexValidator
from django.core.exceptions import ValidationError
import re
class RegForm(forms.Form):
user = forms.CharField( #用户名
label="用户名",
min_length=2,
initial="小小城序员",
disabled=True,
error_messages={
'min_length': '用户名的长度不能小于2'
}
)
password = forms.CharField( #密码
label="密码",
min_length=6,
max_length=20,
widget=widgets.PasswordInput(),
error_messages={
'min_length': '密码的长度不能小于6',
'max_length':'密码的长度不能超过6',
'required': '密码不能为空',
}
)
again_password = forms.CharField( #确认密码
label="确认密码",
min_length=6,
max_length=20,
widget=widgets.PasswordInput(),
error_messages={
'min_length': '确认密码的长度不能小于6',
'max_length': '确认密码的长度不能超过6',
'required': '确认密码不能为空',
}
)
gender = forms.ChoiceField( #性别
label='性别',
widget=widgets.RadioSelect(),
choices=((1, '男'), (2, '女')),
error_messages={
'required': '性别不能为空',
}
)
ancestral_home = forms.ChoiceField( #祖籍
label='祖籍',
choices=((1, '北京市'), (2, '福建省'), (3, '广东省'), (4, '广西省')),
required=False,
)
phone = forms.CharField( #手机号
label='手机号',
error_messages={
'required': '手机号不能为空',
}
)
email = forms.CharField( #邮箱
label='邮箱',
validators=[RegexValidator(r'^[a-zA-Z0-9]+\@[a-zA-Z0-9]+(\.)[a-zA-Z0-9]+$')],
error_messages={
'required': '邮箱不能为空',
'invalid': '邮箱格式不匹配',
}
)
def clean_phone(self): #局部钩子函数,对手机号进行正则匹配
value = self.cleaned_data.get('phone')
if re.match(r'^1[3-9]\d{9}$',value):
return value
raise ValidationError('手机号不匹配')
def clean_again_password(self): #局部钩子函数,对两次的密码进行校验
password = self.cleaned_data.get('password')
again_password = self.cleaned_data.get('again_password')
if password == again_password:
return again_password
raise ValidationError('两次密码不匹配')
def clean(self): #全局的钩子函数
pass
页面register.html
<!--register.html-->
<!DOCTYPE html>
<html lang="zh_CN">
<head>
<meta charset="UTF-8">
<title>注册</title>
</head>
<body>
<form action="" method="post" novalidate>
{% csrf_token %}
<div><!--用户名-->
{{ form_obj.user.label }}
{{ form_obj.user }}
<sapn style="color: red">{{ form_obj.user.errors.0 }}</sapn>
</div>
<div><!--密码-->
{{ form_obj.password.label }}
{{ form_obj.password }}
<sapn style="color: red">{{ form_obj.password.errors.0 }}</sapn>
</div>
<div><!--确认密码-->
{{ form_obj.again_password.label }}
{{ form_obj.again_password }}
<sapn style="color: red">{{ form_obj.again_password.errors.0 }}</sapn>
</div>
<div><!--性别-->
{{ form_obj.gender.label }}
{{ form_obj.gender }}
<sapn style="color: red">{{ form_obj.gender.errors.0 }}</sapn>
</div>
<div><!--祖籍-->
{{ form_obj.ancestral_home.label }}
{{ form_obj.ancestral_home }}
<sapn style="color: red">{{ form_obj.ancestral_home.errors.0 }}</sapn>
</div>
<div><!--手机号码-->
{{ form_obj.phone.label }}
{{ form_obj.phone }}
<sapn style="color: red">{{ form_obj.phone.errors.0 }}</sapn>
</div>
<div><!--邮箱-->
{{ form_obj.email.label }}
{{ form_obj.email }}
<sapn style="color: red">{{ form_obj.email.errors.0 }}</sapn>
</div>
<button>注册</button>
</form>
</body>
</html>
效果:
一开始的注册页面:
当密码与确认密码不一致且手机号码的正则匹配失败时的页面:
上面的注册功能界面显得不太美观。所以,下面记录的就是Django的Form组件配合上Bootstrap样式的组合。
附上代码:
视图view.py
from django.shortcuts import render, HttpResponse
from registerapp.forms import RegForm,RegForm2
def register2(request):
form_obj = RegForm2()
if request.method == 'POST':
form_obj = RegForm2(request.POST)
if form_obj.is_valid():
return HttpResponse("校验成功2")
return render(request, 'register2.html', {'form_obj': form_obj})
校验forms.py
from django import forms
from django.forms import widgets
from django.core.validators import RegexValidator
from django.core.exceptions import ValidationError
import re
class RegForm2(forms.Form):
username = forms.CharField(
label="用户名",
min_length=2,
max_length=6,
error_messages={
'min_length': '用户名的长度不能小于2',
'max_length':'用户名的长度不能大于6',
'required':'用户名不能为空',
}
)
password = forms.CharField(
label="密码",
widget=forms.widgets.PasswordInput(),
error_messages={
'required': '密码不能为空',
}
)
re_password = forms.CharField(
label="确认密码",
widget=forms.widgets.PasswordInput(),
error_messages={
'required': '密码不能为空',
}
)
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
for field in self.fields:
self.fields[field].widget.attrs.update({'class': 'form-control'})
def clean(self):
pwd = self.cleaned_data.get('password')
re_pwd = self.cleaned_data.get('re_password')
if pwd == re_pwd:
return self.cleaned_data
self.add_error('re_password', '两次密码不一致')
raise ValidationError('两次密码不一致')
页面register2.html
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta http-equiv="content-Type" charset="UTF-8">
<meta http-equiv="x-ua-compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Title</title>
<link rel="stylesheet" href="/static/bootstrap-3.3.7/css/bootstrap.css">
</head>
<body>
<div class="container">
<div class="row">
<div class="col-sm-offset-6">
<h3>小小城序员</h3>
</div>
</div>>
</div>
<div class="container">
<div class="row">
<div class="col-sm-8 col-sm-offset-2" style="margin-top: 70px">
<form class="form-horizontal" novalidate action="" method="post">
{% csrf_token %}
<div class="form-group {% if form_obj.username.errors %} has-error {% endif %} "><!--用户名-->
<label for="{{ form_obj.username.id_for_label }}"
class="col-sm-2 control-label">{{ form_obj.username.label }}</label>
<div class="col-sm-10">
{{ form_obj.username }}
<span id="helpBlock2" class="help-block">{{ form_obj.username.errors }}</span>
</div>
</div>
<div class="form-group {% if form_obj.password.errors %} has-error {% endif %} "><!--密码-->
<label for="{{ form_obj.password.id_for_label }}"
class="col-sm-2 control-label">{{ form_obj.password.label }}</label>
<div class="col-sm-10">
{{ form_obj.password }}
<span id="helpBlock2" class="help-block">{{ form_obj.password.errors }}</span>
</div>
</div>
<div class="form-group {% if form_obj.re_password.errors %} has-error {% endif %}"><!--确认密码-->
<label for="{{ form_obj.re_password.id_for_label }}"
class="col-sm-2 control-label">{{ form_obj.re_password.label }}</label>
<div class="col-sm-10">
{{ form_obj.re_password }}
<span id="helpBlock2" class="help-block">{{ form_obj.re_password.errors }}</span>
</div>
</div>
<div class="form-group">
<div class="col-sm-offset-2 col-sm-10">
<button type="submit" class="btn btn-block">Sign in</button>
</div>
</div>
</form>
</div>
</div>
</div>
<script src="/static/Jquery-3.3.1.js"></script>
<script>
$('input').focus(function () {
$(this).next().text('').parent().parent().removeClass('has-error')
})
</script>
</body>
</html>
效果:
一开始的注册页面:
密码与输入密码不一致时:
END!