Django表单模型
在应用新建一个forms.py文件:
from django.contrib.auth.forms import UserCreationForm
from .models import User
from django import forms
from django.utils.translation import gettext as _
#自定义的用户注册表单
class CustomUserCreationForm(UserCreationForm): #继承自标准注册表单
#这里入如果添加了就会展示,要编辑顺序在下面的fields中
email_code = forms.CharField(max_length=6,label=_('邮件验证码'),help_text=_('输入Email收到的验证码'),required=True) # 用于输入邮件确认验证码的字段,required为必填
class Meta(UserCreationForm.Meta):
model = User #基于User模型,要查看user表有什么字段
fields = ('username', 'email', 'email_code', 'password1', 'password2', 'beiyaoqing') # 这是输入要展示的内容和顺序
视图函数:
from django.shortcuts import render, redirect
from .forms import CustomUserCreationForm #导入自定义的注册表单
def register_view(request):
if request.method == 'POST':
form = CustomUserCreationForm(request.POST)
if form.is_valid():
user = form.save()
login(request, user)
# 注册成功后跳转到其他页面
return redirect('login')
else:
form = CustomUserCreationForm()
return render(request, 'register.html', {'form': form})
在视图中为表单传递额外的变量
#视图这边在指定表单的时候
form = ResetpasswordForm2(request.POST,initial={'email': email})
表单那边读取这个变量
class ResetpasswordForm2(forms.ModelForm):
# 表单的字段定义等
def clean(self):
email = self.initial['email'] # 获取传递的email变量
# 其他验证逻辑
return self.cleaned_data
模板简单引用:
<form method="post">
<!-- 注意csrf_token是函数不是变量引用 -->
{% csrf_token %}
{{ form.as_p }}<!-- 显示表全部 -->
<button type="submit">{% trans "注册" %}</button>
</form>
自定义模型表单
在forms.py新建一个表单
#验证邮箱表单
from .models import User
from django import forms
from django.utils.translation import gettext as _
from django.utils import timezone
class VEmailForm(forms.ModelForm):
class Meta:
model = User
fields = ["vcode"] #自定义了一个核验验证码表单
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.fields['vcode'].widget.attrs['placeholder'] = _('输入您收到的验证码')
self.fields['vcode'].widget.attrs['class'] = 'input mb-3'
def clean_vcode(self):
#判断用户是否存在验证码
if not self.instance.vcode:
raise forms.ValidationError(_('没有验证码,您要重新获取验证码'))
#判断用户上次请求时间
print(f'验证码时间{self.instance.vcode_date}')
time_diff = timezone.now() - self.instance.vcode_date #当前时间减去代码创建时间
if time_diff.total_seconds() > 20 * 60: #如果大于20分钟
raise forms.ValidationError(_('验证码已超过20分钟,请重新获取'))
vcode = self.cleaned_data.get('vcode') #获取表单得到的数据段
# 在这里进行验证码核验操作,与数据库中的 User 模型进行比对等
if vcode != self.instance.vcode: #需在视图函数中传入instance=request.user才可去对比
raise forms.ValidationError(_('验证码不正确')) #返回错误信息
#如果验证通过,则清空验证码
#注意如果在表单和视图中同时执行了保存,则表单保存会失效
self.instance.vcode = None # 清空验证码
self.instance.save() # 保存修改
return vcode
视图函数:
#待邮箱验证视图
@login_required
@user_passes_test(v_email,login_url="/")
def active_view(request,diqu):
if request.method == 'POST':
form = VEmailForm(request.POST,instance=request.user)
if form.is_valid():
#先预保存,获得对象
user = form.save(commit=False)
user.is_email = True
user.save()
else:
form = VEmailForm(instance=request.user)#将用户传instance
return render(request, 'active.html', {'form': form})
自己定义样式模板引用
<form method="POST">
{% csrf_token %}
{{ form.vcode }}
{{ form.vcode.errors }}
<button class="button is-dark is-fullwidth" type="submit">提交验证</button>
</form>
自己定义错误提示
{% if form.vcode.errors %}
<ol>
{% for error in form.vcode.errors %}
<li><strong class="dd">{{ error|escape }}</strong></li>
{% endfor %}
</ol>
{% endif %}
表单输出所有错误提示
<style>
.errorlist {
color: rgb(206, 0, 0);
font-weight: bold;
}
</style>
{{ form.non_field_errors }}
从表单中取用户信息并修改数据库
注意如果在表单和视图中同时执行了保存,则表单保存会失效
#通过表单获取用户模型
if form.is_valid():
print('验证通过')
user = form.save(commit=False) #获取对象先不保存
user.is_email = True
user.save()