栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Python

Django小记 表单-Form模块

Python 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

Django小记 表单-Form模块

文章目录
  • HTML 中的表单
  • 构造Django表单类
    • 表单字段
    • 字段属性
    • Django内置插件:
    • is_valid()、cleaned_data
    • 二次验证
  • 表单与视图处理
    • GET
    • POST
    • is_bound
  • 表单与模板
    • 框架结构
    • 常用表单模板
    • 循环表单
    • field 常用属性
  • 深入学习
    • 表单渲染格式
  • class meta()


HTML 中的表单
  • 这是 HTML 中的一个表单元素
    • action : 发送的目的地
    • method : HTTP 方法
    • 第一个:需要提交的数据
    • 第二个:提交按钮

构造Django表单类

示例:

from django import forms

class StudentLoginForm(forms.Form):
    student_num = forms.CharField(
        label='学号',
        required=True,
        max_length=11,
        widget=forms.TextInput(attrs={
            'class': 'form-control mb-0',
            'placeholder': "请输入学号"
        }),
        error_messages={
            'required': '学号不能为空',
            'max_length': '长度不能超过50个字符',
        }
    )
    password = forms.CharField(
        label='密码',
        required=True,
        min_length=6,
        max_length=50,
        widget=forms.PasswordInput(attrs={
            'class': 'form-control mb-0',
            'placeholder': "请输入密码"
        }),
        error_messages={
            'required': '用户名不能为空',
            'min_length': '长度不能少于6个字符',
            'max_length': '长度不能超过50个字符',
        }
    )
  • 每一个表单类都要继承 django.forms.Form

表单字段
Django内置字段Django内置字段
BooleanFieldCharField
ChoiceFieldTypedChoiceField
DateFieldDateTimeField
DecimalFieldDurationField
EmailFieldFileField
FilePathFieldFloatField
ImageFieldIntegerField
GenericlPAddressFieldMultipleChoiceField
TypedMultipleChoiceFieldNullBooleanField
RegexFieldSlugField
TimeFieldURLField
UUIDFieldComboField
MultiValueFieldSplitDateTimeField
ModelChoiceFieldModelMultipleChoiceField
字段属性
password = forms.CharField(
    label='密码',
    required=True,
    min_length=6,
    max_length=50,
    widget=forms.PasswordInput(attrs={
        'class': 'form-control mb-0',
        'placeholder': "请输入密码"
    }),
    error_messages={
        'required': '用户名不能为空',
        'min_length': '长度不能少于6个字符',
        'max_length': '长度不能超过50个字符',
    }
)
  • label
    • 用于设置说明标签
  • initial
    • 初始值
  • required
    • True:必填字段
  • max_length
    • 最大长度
  • min_length
    • 最小长度
  • widget
    • 指定 HTML 中的一种 input 元素类型
    • 也就是自定义插件
Django内置插件:
--
TextInput(Input)NumberInput(TextInput)
EmailInput(TextInput)URLInput(TextInput)
PasswordInput(TextInput)HiddenInput(TextInput)
textarea(Widget)DateInput(DateTimebaseInput)
DateTimeInput(DateTimebaseInput)TimeInput(DateTimebaseInput)
CheckboxInputSelect
NullBooleanSelectSelectMultiple
RadioSelectCheckboxSelectMultiple
FileInputClearableFileInput
MultipleHiddenInputSplitDateTimeWidget
SplitHiddenDateTimeWidgetSelectDateWidget
  • RadioSelect()
from django import forms
gender = forms.ChoiceField(
	choices=((1, '男'), (2, '女'), (3, '保密'))
	label="性别",
	initial=3,
	widget=forms.RadioSelect()
	)	
  • Select() ---- 单选
from django import forms
gender = forms.ChoiceField(
	choices=((1, '男'), (2, '女'), (3, '保密'))
	label="性别",
	initial=3,
	widget=forms.Select()
	)	
  • SelectMultiple() ---- 多选
from django import forms
gender = forms.MultipleChoiceField(
	choices=((1, '苹果'), (2, '香蕉'), (3, '西瓜'))
	label="水果",
	initial=[1, 3],
	widget=forms.SelectMultiple()
	)	
  • CheckboxInput() ---- 单选
from django import forms
gender = forms.ChoiceField(
	label="是否记住密码",
	initial='checked',
	widget=forms.CheckboxInput()
	)	
  • CheckboxSelectMultiple() ---- 多选
from django import forms
gender = forms.MultipleChoiceField(
	choices=((1, '苹果'), (2, '香蕉'), (3, '西瓜'))
	label="水果",
	initial=[1, 3],
	widget=forms.CheckBoxSelectMultiple()
	)	
  • choice
    choices 可以从数据库中获取:
from django import forms

class TestForm(forms.Form):
	user = forms.ChoiceField(
		# choices = (...)
		initial=3,
		widget=forms.Select()
	)
	def __init__(self, *args, **kwargs):
		super().__init__(*args,**kwargs)
		# self.fields['user'].choices=((1, '上海'), (2, '北京'),(3, '成都'))
		# or
		self.fields['user'].choices = models.Classes.objects.all().value_list('id', 'caption')
  • error_message
    • 错误信息字典
  • help_text
    • 帮助信息(显示在标签旁边)
  • validators=[]
    • 自定义验证规则
  • RegexValidator 验证器
from django.forms import Form,CharField
from django.core.validators import RegexValidator

class TestForm(Form):
	user = CharField(
		validators=[RegexValidators(r'^[0-9]+$','请输入数字'),
			RegexValidators(r'^[0-9]+666$', '数字必须以 666 结尾')]
	)
  • 自定义验证函数
import re
from django import forms
from django.core.exceptions import ValidationError
# or
# from django.forms import ValidationError

def stu_num_validate(value):
	stu_num_re = re.compile(r'^20210[123][0-9]{4}$')
	if not stu_num_re.match(value):
		raise ValidationError('学号格式错误')
	return value

class TestFrom(forms.Form):
	student_num = forms.CharField(
		max_length=11,
		min_length=10,
		# 自定义验证函数
		validators=[stu_num_validator,],
		widget=forms.TextInput(attrs={'class':'form-control',
									'placeholder':'输入学号'}),
		error_messages={
			'required': '不能为空',
			'min_length': '学号为10位',
		}
						
  • localize
    • 是否支持本地化
  • disabled
    • 是否可以编辑
  • label_suffix
    • Label 内容后缀

is_valid()、cleaned_data
  • 每个表单都有一个内置的 is_valid() 方法,验证数据是否合法
    • 合法则返回 True
    • 并将所有的表单数据转存到 cleaned_data 属性中(字典形式)。
  • 一旦表单接收数据并验证通过,就可以从form.cleaned_data字典中读取所有的表单数据

二次验证
  • 二次验证固定写法 clean_formname()
    • clean_ 开头,后接变量名
class StudentLoginForm(forms.Form):
    student_num = forms.CharField(...)
    password = forms.CharField(...)

    # 二次验证函数的名字是固定写法,以clean_开头,后面跟上字段的变量名
    def clean_student_num(self):
        # 通过了validators的验证之后,载进行二次验证
        student_num = self.cleaned_data['student_num']
        try:
         	# 使用student_num获取Django用户
            user = User.objects.get(username=student_num) 
        except User.DoesNotExist:
            raise forms.ValidationError('学号不存在', 'invalid')
        else:
            return student_num

表单与视图处理
  • 构造表单类后,就可以在视图中进行实例化、处理

示例:

from django.views import View
from student.forms import StudentLoginForm

class StudentLoginView(View):
    def get(self, request):
        """
        显示登录页面
        """
        # 实例化表单
        form = StudentLoginForm()
        return render(request, 'login.html', {'form': form})  # 渲染模板

    def post(self, request):
        """
        提交登录页面表单
        """
        form = StudentLoginForm(request.POST)  # 接收Form表单
        # 验证表单
        if form.is_valid():
            student_num = request.POST['student_num']  # 获取学号
            password = request.POST['password']  # 获取密码
            user = authenticate(request, username=student_num, password=password)  # 授权校验
            if user is not None:  # 校验成功,获得返回用户信息
                if user.is_staff == 1:
                    # 如果 是管理员账户,那么跳转到管理员登录
                    messages.add_message(request, messages.INFO, '您好!管理员')
                    return redirect('/admin')
                login(request, user)  # 登录用户,设置登录session
                request.session['uid'] = user.id  # 设置用户名的session
                request.session['username'] = user.student.name  # 设置用户名的session
                request.session['student_num'] = user.student.student_num  # 设置用户名的session
                return HttpResponseRedirect('/')
            else:
                messages.add_message(request, messages.ERROR, '用户名和密码不匹配')  # 提示错误信息
        return render(request, 'login.html', {'form': form})  # 渲染模板

也可写成视图函数:

def student_login(request):
	if request.method == 'GET':
		# 实现 Get 方法时操作
		# 对应上述视图类的 get() 方法
	elif request.method == 'POST':
		# POST 方法时 对应的操作
		# 对应上述视图类的 post() 方法
	return render(request, 'login.html', {'form': form})

GET
  • GET 方法请求页面时,返回空的表单,让用户可以填写数据
POST
  • POST 方法,接收表单数据,并验证;
  • 如果不合法,返回一个包含先前数据的表单给前端,方便用户修改。

is_bound
  • 通过表单 is_bound 属性可以获知一个表单已经绑定了数据,还是一个空表。

表单与模板
框架结构

    {% csrf_token %}
    
{{form.student_num}} {{form.student_num.errors}}
  • POST方法必须添加{% csrf_token %},用于处理 csrf 安全机制
  • 提交按钮自己写
  • label 可以简单渲染生成: {{ field.label_tag }}

    {% csrf_token %}
    
{{form.student_num.label_tag}} {{form.student_num}} {{form.student_num.errors}}

常用表单模板
{% include "form_01.html" %}
{% for field in form %}
    
{{ field.errors }} {{ field.label_tag }} {{ field }}
{% endfor %}

防止表单冲突

{% include "form_01.html" with form=comment_form %}
{% for field in comment_form %}
......

循环表单
  • {% for one in *** %}..... {% endfor %} 语法
{% for field in form %}
    
{{ field.label_tag }} {{ field }} {{ field.errors }} {% if field.help_text %}

{{ field.help_text|safe }}

{% endif %}
{% endfor %}

field 常用属性
  • {{ field.属性 }}
属性说明
label字段对应的 label 属性。
label_tag自动生成 label 标签。
id_for_label自定义字段标签的 id 。
value当前字段的值。
html_name指定字段生成的 input 标签中 name 属性的值。
help_text字段的帮助属性。
errors包含错误信息的元素。
is_hidden用于判断当前字段是否为隐藏字段
field返回字段的参数列表

深入学习
表单渲染格式