Form表单分为三种:Form表单都继承自django.forms
1、简单表单的使用(Form)
2、模型表单(ModelForm)
3、模型表单的自定义验证
实例1:简单表单的使用,博客用户注册表单
步骤
在项目目录下创建forms.py,表单文件
from django import forms
class RegisterForm(forms.Form): username = forms.CharField(label='用户名',max_length=20) #CharField 默认对应text类 password = forms.CharField(label='密码',max_length=8, #字段名与input类中一一对应,会被渲染成input类型 min_length=6, #label属性会被渲染成label标签的内容 widget=forms.PasswordInput(attrs={'placehodler':'请输入长度为6-8位的密码'}), error_messages={ 'min_length':'密码长度小于6位', 'max_length':'密码长度大于8位' }) password_repeat = forms.CharField(label='请再次输入密码',widget=forms.PasswordInput()) email = forms.EmailField(required=False) #这个选项表示这个选项不是必填项,默认是必填选项 #自定义验证密码,重写clean方法 def clean(self): cleaned_data = super().clean() #继承父类的clean() 方法,使用验证is_valid()方法会调用clean() password = cleaned_data.get('password') password_repeat = cleaned_data.get('password_repart') if password != password_repeat: msg = '密码不一致!' self.add_error('password_repeat',msg)
在视图view.py中添加:
def register(request): if request.method == 'GET': form = RegisterForm() if request.method == 'POST': form = RegisterForm(request.POST) if form.is_valid(): #调用is_valid()方法进行验证时,需要调用clean() return HttpResponse('注册成功') return render(request, 'teacher/register.html', context={'form': form})
定义渲染页面register.html代码:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> <style> * { margin: 0; padding: 0; } </style> </head> <body> <form action="" method="post"> #填写完毕后,提交出来 {% csrf_token %} {{ form.as_p }} #将forms表单中的属性渲染出来 <input type="submit" value="注册"> </form> </body> </html>
在路由urls.py中添加:
path('register/',views.register,name='register'),
实例二:模型表单
2.1、修改表单,自定义验证身份证信息,以及使用标签添加样式,字段错误后显示样式等。
forms.py中添加如下代码:
from django import forms from teacher.models import StudentDetail,Student#模型表单 class StudentForm(forms.ModelForm): class Meta: model = Student #指定使用的模型 exclude = ['is_deleted'] #排除列表中的字段 # fields = ['name','age'] #添加 class StudentDetailForm(forms.ModelForm): class Meta: model = StudentDetail exclude = ['student'] def clean_num(self): #自定义验证身份证信息 data = self.cleaned_data.get('num') if not data[:-1].isdigit(): raise forms.ValidationError('你输入的号码不正确') return data
view.py中添加
from teacher.models import Student,Grade,StudentDetail,Course,Enroll
from teacher.forms import RegisterForm,StudentDetailForm,StudentForm
def new_edit(request,pk):
section = '学生信息修改' student = Student.objects.get(pk =pk) form = StudentForm(instance=student) try: detail_form = StudentDetailForm(instance=student.studentdetail) except: #说明学生对象还没有学生详情 student_detail = StudentDetail() student_detail.student=student student_detail.save() detail_form = StudentDetailForm(instance=student_detail) if request.method == 'POST': form = StudentForm(request.POST,instance=student) detail_form = StudentDetailForm(request.POST,instance=student.studentdetail) if form.is_valid() and detail_form.is_valid(): form.save() detail_form.save() return redirect(reverse('teacher:students')) return render(request,'teacher/student_edit_form.html',context={ 'section':section, 'student':student, 'form':form, 'detail_form':detail_form })
student_edit_form.html代码如下:
{% extends 'teacher/base.html' %} {% block title %}添加学生{% endblock %} {% load customer_tags %} {% block section %} {{ section }}{% endblock %} {% block content %} <form class="form-horizontal" method="post"> {% csrf_token %} {% for field in form %} {# field.errors 字段的错误#} <div class="form-group {% if field.errors %}has-error{% endif %}"> #错误字段显示红色 {% for error in field.errors %} #渲染错误信息 <label for="{{ field.id_for_label }}" class="col-sm-2 control-label">{{ error }}</label> {% endfor %} <label for="{{ field.id_for_label }}" class="col-sm-2 control-label">{{ field.label }}</label> #渲染正式信息 <div class="form-group"> <label class="col-sm-2 control-label">{% add_class field 'form-control' %}</label> #使用标签添加样式 </div> </div> {% endfor %} {% for field in detail_form %} <div class="form-group"> {% for error in field.errors %} <label for="{{ field.id_for_label }}" class="col-sm-2 control-label">{{ error }}</label> {% endfor %} <label for="{{ field.id_for_label }}" class="col-sm-2 control-label">{{ field.label }}</label> <div class="form-group"> <label class="col-sm-2 control-label">{% add_class field 'form-control' %}</label> </div> </div> {% endfor %} <button type="submit" class="btn btn-primary">提交</button> </form> {% endblock %}
使用标签添加样式代码如下,在customer_tags.py中添加:
@register.simple_tag() def add_class(field,class_str): return field.as_widget(attrs={'class':class_str})
在urls.py 中添加如下路由:
path('newedit/<int:pk>/',views.new_edit,name='new_edit'),
渲染效果如下:
2.2 使用模型表单重新定义“添加”学生
view.py中添加
def new_add(request): section = '添加学生' if request.method == 'GET': form = StudentForm() detail_form = StudentDetailForm() if request.method == 'POST': form = StudentForm(request.POST) detail_form = StudentDetailForm(request.POST) if form.is_valid() and detail_form.is_valid(): student = form.save() #加上commit=False不会去真的保存到数据库中 #因为还要给它加上外键关联对象 student_detail = detail_form.save(commit=False) student_detail.student = student student_detail.save() return redirect(reverse('teacher:students')) return render(request,'teacher/student_edit_form.html', context={ 'section':section, 'form':form, 'detail_form':detail_form })
更新urls.py路由信息
path('student_add/',views.new_add,name='student_add'),