一、常见的表单元素
- 表单标签---<form>
- 单行文本框、多行文本框
- 选择(单选、多选、下拉选择)
- 隐藏表单域
- 表单按钮
- 文件上传框
二、表单的使用的步骤
- 创建表单类
# 示例代码 from django import forms class LoginForm(forms.Form): username = forms.CharField(label="用户名",max_length=100)
- 添加到视图函数
# 示例代码 def form(request): #表单对象 form = LoginForm() return render(request,'form.html'.{ 'form':form })
- 渲染到模板
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <body> <form action="" method="post"> {% csrf_token %} {{ form.as_p }} <input type="submit" value="提交"> </form> </body> </html>
as_p() 以p标签方式渲染
as_ul() 以列表方式渲染
as_table() 以表格方式渲染
- 在视图中处理表单数据
def form(request): # 表单对象 if request.mothod == 'POST': form = LoginForm(request.POST) if form.is_valid(): data = form.cleaned_data print('data:',data) else: form = LoginFrom() return rander(request,'form.html',{ 'form':form})
一、表单字段(Field)
- 表单字段继承django.forms.Field
- 每个字段都具有核心参数
- 每个字段都可以有自定义的验证逻辑
- 每个字段都有钩子函数,方便扩充功能
label ----- label标签(输入框前的文字描述)
required-----是否为必填,默认为必填
help_text -----帮助文字
initial ---- 初始化数据
error_messages ----覆盖字段引发异常后的错误显示
widget ----- 定制界面显示方式(如:文本框,选择框)
disabled --- 禁用表单,界面上不可操作
二、Django内置的字段
- 文本/字符串
CharField ----字符串输入
EmailField ----邮件地址输入
URLField ---- URL地址输入
UUIDField ----- uuid字符串输入
# 示例代码
class UserRegForm(forms.Form):
"""用户注册表单"""
username = forms.EmailField(label='用户名',max_length=200,min_length=5)
- 数值(整数、小数)
IntegerField ---整数输入
FloatField ---- 浮点数输入
DecimalField ---- 小数输入(更精确)
- 选择(单选、多选)
ChoiceField ---- 单选
MultipleChoiceField ---- 多选
TypedChoiceField ------ 高级选择(支持结果转换类型)
- 日期/时间
DateField --- 日期选择
DateTimeField ------ 日期时间选择
DurationField ----- 时间片段timedelta
TimeField ---- 时间选择
- 文件/文件上传
ImageField ---- 图片
FileField ----- 文件
FilePathField ----- 文件路径
- 布尔
BooleanField ------ True\False
NullBooleanField ------ None\True\False
- 正则表达式
RegexField ------ 正则输入
三、在视图中获取表单值
GET请求
request.GET.get('name',None)
POST请求
request.POST.get('name',None)
文件对象
request.FILES.get('name',None)
四、Form对象的方法
- as_p()/as_ul()/as)talble() -----渲染表单
- is_valid() ------ 表单是否已经通过验证
- clean() ------- 调用表单的验证/自定义的验证
五、Form对象的属性
is_bound ----- 是否已经绑定了数据
cleaned_data ------ 访问表单验证后的数据
errors ----- 表单验证后的错误信息
initial ----- 初始化数据
def form(request):
# 表单对象
if request.mothod == 'POST':
form = LoginForm(request.POST)
# 表单验证
if form.is_valid():
# 访问通过后的数据 cleaned_data
data = form.cleaned_data
print('data:',data)
else:
# 表单没有通过验证
print(form.errors)
else:
form = LoginFrom()
return rander(request,'form.html',{
'form':form})
六、自定义界面显示
内置的widgets
- 文本输入
TextInput(单行文本) NumberInput(数字) EmailInput(邮件) URLInput PasswordInput(密码) HiddenInput (隐藏表单域)
DateInput(日期) DateTimeInput(日期加时间) TimeInput(时间) Textarea(多行文本)
class LoginForm(forms.Form):
"""" 登录表单 """
username = forms.CharField(label='用户名',max_length=100,required=False)
password = forms.CharField(label='密码',
max_length=120, min_length=6,
widget=forms.PasswordInput) #widget使用
- 选择输入
Select (下拉选择,单选) NullBooleanSelect RadioSelect(单选) SelectMultiple (多选) CheckboxSelectMultiple(复选框)
- 文件上传
FileInput
- 复合Widget
MultipleHiddenInput SplitDateTimeWidget SplitHiddenDateTimeWidget SelectDateWidget
三、表单验证
表单验证的步骤
- 定义clean_xx验证方法
- 获取对应的字段值并验证
- 验证失败触发forms.ValidationError异常
- 返回验证后的数据
- 在html中页面显示错误
class LoginForm(forms.Form):
"""" 登录表单 """
username = forms.CharField(label='用户名',max_length=100,required=False)
password = forms.CharField(label='密码', max_length=120, min_length=6,widget=forms.PasswordInput)
# clean钩子函数,后面加验证的字段
def clean_username(self):
"""验证用户名"""
username = self.cleaned_data['username']
pattern = r'^[0-9]{10}$'
if not re.search(pattern,username):
raise forms.ValidationError('请输入手机号码')
return username
视图views.py中
def user_login(request):
if request.method == 'POST':
form = LoginForm(data=request.POST)
if form.is_valid():
print('表单验证通过')
else:
print(form.errors)
else:
form = LoginForm()
return render(request,'user_login.html',{
'form':form,
})
html中
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title></title>
</head>
<body>
<h3>用户登录</h3>
<form action="." method="post">
{% csrf_token %}
{# {{ form.as_p }}#}
<div>
{{ form.username.label }}
{{ form.username }}
{{ form.username.errors.as_text }}
</div>
<input type="submit" value="登录">
</form>
</body>
</html>
四、从ORM模型中创建表单
Meta类的配置选项
model ------ 对应的ORM模型
fields ------ ORM模型中哪些字段需要出现在表单中
exclude ----- ORM模型中哪些字段不需要出现在表单中(排除不能编辑的字段,editable=False)
help_texts ------ 重写使用帮助信息
labels ----- 设置表单输入前的文字提示
widgets ------ 自定义界面显示
error_messages ----- 配置表单验证中错误提示
ORM模型中
class User(CommonModel):
USER_STATUS = (
(1,'正常'),
(0,'删除'),
)
username = models.CharField('用 户名',max_length=128)
password = models.CharField('密码',max_length=256)
nickname = models.CharField('昵称',max_length=256,null=True,blank=True)
avatar = models.ImageField('用户头像',upload_to='avatar',null=True,blank=True)
status = models.SmallIntegerField('用户状态',default=1,choices=USER_STATUS)
is_super = models.BooleanField('是否为超级用户',default=False)
created_at = models.DateTimeField('注册时间', auto_now_add=True)
updated_at = models.DateTimeField('最后修改时间', auto_now=True)
class Meta:
db_table = 'accounts_user'
表单form中
from django import forms
from account.models import User
class UserChangeForm(forms.ModelForm):
"""从模型创建表单 用户基本信息修改"""
class Meta:
model = User
# fields = ('username','password','nickname','avatar')
exclude = ('status',)
labels = {
'username':'手机号码'
}
widgets = {
'password':forms.PasswordInput
}
error_messages = {
'username':{
'max_length':'用户名超过了最大长度限制'
}
}
4.1 修改模型表单
添加表单验证
保存用户详细信息 views.py中
def user_change(request):
"""用户信息维护 - 基于ORM创建的表单"""
if request.method == 'POST':
form = UserChangeForm(data=request.POST)
if form.is_valid():
# save方法提交事务
form.save()
print('表单通过')
else:
print(form.errors)
else:
form = UserChangeForm()
return render(request,'user-change.html',{
'form':form,
})
五、通过表单实现文件上传
- 表单设置enctype="multipart/form-data"
- 在视图中通过request.FILES来获取文件对象
5.1将文件保存到磁盘
视图views中
def upload_user_form(request):
"""文件上传-表单上传"""
if request.method == 'POST':
file = request.FILES.get('avatar',None)
if file:
# MEDIA_ROOT在项目setting中配置
filename = os.path.join(settings.MEDIA_ROOT,'test.jpg')
with open(filename,'wb+') as d:
for chunk in file.chunks():
d.write(chunk)
print('文件上传成功')
return render(request,'upload_user_form.html')
html中
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>表单上传文件</title>
</head>
<body>
<form action="." method="post" enctype="multipart/form-data">
{% csrf_token %}
<input type="file" name="avatar">
<input type="submit" value="提交">
</form>
</body>
</html>
5.2 使用Django表单上传
表单中的相关字段
forms.ImageField
表单类的参数
form = AvatarUploadForm(request.POST,request.FILES)
表单中定义类
class AvatarUploadForm(forms.Form):
"""使用表单上传用户头像"""
avatar = forms.ImageField(label="用户头像")
视图函数中
def upload_user_form2(request):
"""文件上传-表单上传"""
if request.method == 'POST':
form = AvatarUploadForm(data=request.POST,files=request.FILES)
# 验证表单
if form.is_valid():
file = form.cleaned_data['avatar']
if file:
filename = os.path.join(settings.MEDIA_ROOT,'test.jpg')
with open(filename,'wb+') as d:
for chunk in file.chunks():
d.write(chunk)
print('文件上传成功')
else:
form = AvatarUploadForm()
return render(request,'upload_user_form.html',{
'form':form
})
5.3 结合ORM实现文件上传
ORM中相关的类型
ImageField
FileField
类型参数upload_to,上传文件路径 %Y/%/m(文件路径下会生成时间文件夹)
models.FileField(upload_to='uploads/%Y/%m/%d/')
model模型中
class User(CommonModel):
avatar = models.ImageField('用户头像',upload_to='avatar/%Y/%m',null=True,blank=True)
class Meta:
db_table = 'accounts_user'