python3开发进阶-Django框架的Form表单系统和基本操作详解编程语言
2023-06-13 09:20:36 时间
什么是Form组件
常用字段和插件
自定义校验的方式
补充进阶
一、什么是Form组件
我们之前在HTML页面中利用form表单向后端提交数据时,都会写一些获取用户输入的标签并且用form标签把它们包起来。
与此同时我们在好多场景下都需要对用户的输入做校验,比如校验用户是否输入,输入的长度和格式等正不正确。
如果用户输入的内容有错误就需要在页面上相应的位置显示对应的错误信息.。
Django form组件就实现了上面所述的功能。
总结一下,其实form组件的主要功能如下:
生成页面可用的HTML标签 对用户提交的数据进行校验 保留用户输入的内容 1、普通的登录 views.pydef login(request): error_msg = "" if request.method == "POST": username = request.POST.get("username") pwd = request.POST.get("pwd") if username == "duoduo" and pwd == "123456": return HttpResponse("OK") else: error_msg = "用户名或密码错误" return render(request, "login.html", {"error_msg": error_msg})login.html
!DOCTYPE html html lang="en" head meta charset="UTF-8" title login /title style .error { color: red; /style /head body form action="/login/" method="post" {% csrf_token %} label for="username" 用户名 /label input type="text" name="username" id="username" label for="pwd" 密码 /label input type="password" name="pwd" id="pwd" span input type="submit" value=登入 span {{ error_msg }} /form /body /html2、使用form组件登入 views.py
先定义好一个LoginForm类。
class LoginForm(forms.Form): username = forms.CharField(min_length=8, label="用户名") pwd = forms.CharField(min_length=6, label="密码")login2.html
form_obj = LoginForm(request.POST) if form_obj.is_valid(): #调用form提供的一个校验的方法 username = form_obj.cleaned_data.get("username") pwd = form_obj.cleaned_data.get("pwd") if username == "duoduo" and pwd == "123456": return HttpResponse("OK") else: error_msg = "用户名或密码错误" return render(request, "login2.html", {"form_obj": form_obj, "error_msg": error_msg})
!DOCTYPE html html lang="en" head meta charset="UTF-8" title login /title style .error { color: red; /style /head body form action="/login2/" method="post" novalidate {% csrf_token %} {{ form_obj.username.label }} {{ form_obj.username }} span {{ form_obj.username.errors.0 }} {{ form_obj.pwd.label }} {{ form_obj.pwd }} span {{ form_obj.pwd.errors.0 }} input type="submit" value=登入 span {{ error_msg }} /form /body /html
看网页效果发现 也验证了form的功能:
自定义一个form类 生成一个form类的实例对象 前端页面是form类的对象生成的 生成HTML标签功能 (在后端)当用户名和密码输入为空或输错之后 页面都会提示 用户提交校验功能 当用户输错之后 再次输入 上次的内容还保留在input框 保留上次输入内容 二、常用字段与插件创建Form类时,主要涉及到 【字段】 和 【插件】,字段用于对用户请求数据的验证,插件用于自动生成HTML;
initial初始值,input框里面的初始值。
class LoginForm(forms.Form): username = forms.CharField( min_length=8, label="用户名", initial="duoduo" # 设置默认值 pwd = forms.CharField(min_length=6, label="密码")error_messages
重写错误信息。
class LoginForm(forms.Form): username = forms.CharField( min_length=8, label="用户名", initial="多多", error_messages={ "required": "不能为空", "invalid": "格式错误", "min_length": "用户名最短8位" pwd = forms.CharField(min_length=6, label="密码")password
class LoginForm(forms.Form): ... pwd = forms.CharField( min_length=6, label="密码", widget=forms.widgets.PasswordInput(radioSelect
attrs={class: c1},
render_value=True) )
单radio值为字符串
class LoginForm(forms.Form): username = forms.CharField( min_length=8, label="用户名", initial="多多", error_messages={ "required": "不能为空", "invalid": "格式错误", "min_length": "用户名最短8位" pwd = forms.CharField(min_length=6, label="密码") gender = forms.fields.ChoiceField( choices=((1, "男"), (2, "女"), (3, "保密")), label="性别", initial=3, widget=forms.widgets.RadioSelect )单选Select
class LoginForm(forms.Form): ... hobby = forms.fields.ChoiceField( choices=((1, "篮球"), (2, "足球"), (3, "双色球"), ), label="爱好", initial=3, widget=forms.widgets.Select )多选Select
class LoginForm(forms.Form): ... hobby = forms.fields.MultipleChoiceField( choices=((1, "篮球"), (2, "足球"), (3, "双色球"), ), label="爱好", initial=[1, 3], widget=forms.widgets.SelectMultiple )单选checkbox
class LoginForm(forms.Form): ... keep = forms.fields.ChoiceField( label="是否记住密码", initial="checked", widget=forms.widgets.CheckboxInput )多选checkbox
class LoginForm(forms.Form): ... hobby = forms.fields.MultipleChoiceField( choices=((1, "篮球"), (2, "足球"), (3, "双色球"),), label="爱好", initial=[1, 3], widget=forms.widgets.CheckboxSelectMultiple )
关于choice的注意事项:
在使用选择标签时,需要注意choices的选项可以从数据库中获取,但是由于是静态字段 ***获取的值无法实时更新***,那么需要自定义构造方法从而达到此目的。
方式一:
from django.forms import Form from django.forms import widgets from django.forms import fields class MyForm(Form): user = fields.ChoiceField( # choices=((1, 上海), (2, 北京),), initial=2, widget=widgets.Select def __init__(self, *args, **kwargs): super(MyForm,self).__init__(*args, **kwargs) # self.fields[user].choices = ((1, 上海), (2, 北京),) # 或 self.fields[user].choices = models.Classes.objects.all().values_list(id,caption)
方式二:
from django import forms from django.forms import fields from django.forms import models as form_model
class FInfo(forms.Form): authors = form_model.ModelMultipleChoiceField(queryset=models.NNewType.objects.all()) # authors = form_model.ModelChoiceField(queryset=models.NNewType.objects.all())
Field required=True, 是否允许为空 widget=None, HTML插件 label=None, 用于生成Label标签或显示内容 initial=None, 初始值 help_text=, 帮助信息(在标签旁边显示) error_messages=None, 错误信息 {required: 不能为空, invalid: 格式错误} show_hidden_initial=False, 是否在当前插件后面再加一个隐藏的且具有默认值的插件(可用于检验两次输入是否一直) validators=[], 自定义验证规则 localize=False, 是否支持本地化 disabled=False, 是否可以编辑 label_suffix=None Label内容后缀
DateField(BaseTemporalField) 格式:2018-09-01 TimeField(BaseTemporalField) 格式:11:12 DateTimeField(BaseTemporalField)格式:2018-09-01 11:12 DurationField(Field) 时间间隔:%d %H:%M:%S.%f ... RegexField(CharField) regex, 自定制正则表达式 max_length=None, 最大长度 min_length=None, 最小长度 error_message=None, 忽略,错误信息使用 error_messages={invalid: ...} EmailField(CharField) ... FileField(Field) allow_empty_file=False 是否允许空文件 ImageField(FileField) ... 注:需要PIL模块,pip3 install Pillow 以上两个字典使用时,需要注意两点: - form表单中 enctype="multipart/form-data" - view函数中 obj = MyForm(request.POST, request.FILES) URLField(Field) ...
empty_label="---------", # 默认空显示内容 to_field_name=None, # HTML中value的值对应的字段 limit_choices_to=None # ModelForm中对queryset二次筛选 ModelMultipleChoiceField(ModelChoiceField) ... django.forms.models.ModelMultipleChoiceField
TypedMultipleChoiceField(MultipleChoiceField) coerce = lambda val: val 对选中的每一个值进行一次转换 empty_value= 空值的默认值 ComboField(Field) fields=() 使用多个验证,如下:即验证最大长度20,又验证邮箱格式 fields.ComboField(fields=[fields.CharField(max_length=20), fields.EmailField(),]) MultiValueField(Field) PS: 抽象类,子类中可以实现聚合多个字典去匹配一个值,要配合MultiWidget使用 SplitDateTimeField(MultiValueField) input_date_formats=None, 格式列表:[%Y--%m--%d, %m%d/%Y, %m/%d/%y] input_time_formats=None 格式列表:[%H:%M:%S, %H:%M:%S.%f, %H:%M] FilePathField(ChoiceField) 文件选项,目录下文件显示在页面中 path, 文件夹路径 match=None, 正则匹配 recursive=False, 递归下面的文件夹 allow_files=True, 允许文件 allow_folders=False, 允许文件夹 required=True, widget=None, label=None, initial=None, help_text= GenericIPAddressField protocol=both, both,ipv4,ipv6支持的IP格式 unpack_ipv4=False 解析ipv4地址,如果是::ffff:192.0.2.1时候,可解析为192.0.2.1, PS:protocol必须为both才能启用 SlugField(CharField) 数字,字母,下划线,减号(连字符) ... UUIDField(CharField) uuid类型
Django form内置字段
三、自定义校验的方式方式一正则:
from django.forms import Form from django.forms import widgets from django.forms import fields from django.core.validators import RegexValidator class MyForm(Form): user = fields.CharField( validators=[RegexValidator(r^[0-9]+$, 请输入数字),
RegexValidator(r^159[0-9]+$, 数字必须以159开头)], )
方式二:
import re from django.forms import Form from django.forms import widgets from django.forms import fields from django.core.exceptions import ValidationError # 自定义验证规则 def mobile_validate(value): mobile_re = re.compile(r^(13[0-9]|15[012356789]|17[678]|18[0-9]|14[57])[0-9]{8}$) if not mobile_re.match(value): raise ValidationError(手机号码格式错误) class PublishForm(Form): title = fields.CharField(max_length=20, min_length=5, error_messages={required: 标题不能为空, min_length: 标题最少为5个字符, max_length: 标题最多为20个字符}, widget=widgets.TextInput(attrs={class: "form-control", placeholder: 标题5-20个字符}))四、补充进阶 1、应用Bootstrap样式
phone = fields.CharField(validators=[mobile_validate, ], error_messages={required: 手机不能为空}, widget=widgets.TextInput(attrs={class: "form-control", placeholder: u手机号码})) email = fields.EmailField(required=False, error_messages={required: u邮箱不能为空,invalid: u邮箱格式错误}, widget=widgets.TextInput(
attrs={class: "form-control",
placeholder: u邮箱}))
!DOCTYPE html html lang="en" head meta charset="UTF-8" link rel="stylesheet" href="/static/bootstrap/css/bootstrap.min.css" title login /title /head body div div form action="/login2/" method="post" novalidate {% csrf_token %} div label for="{{ form_obj.username.id_for_label }}" {{ form_obj.username.label }} /label div {{ form_obj.username }} span {{ form_obj.username.errors.0 }} /span /div /div div label for="{{ form_obj.pwd.id_for_label }}" {{ form_obj.pwd.label }} /label div {{ form_obj.pwd }} span {{ form_obj.pwd.errors.0 }} /span /div /div div label {{ form_obj.gender.label }} /label div div {% for radio in form_obj.gender %} label for="{{ radio.id_for_label }}" {{ radio.tag }}{{ radio.choice_label }} /label {% endfor %} /div /div /div div div button type="submit" 注册 /button /div /div /form /div /div script src="/static/jquery-3.2.1.min.js" /script script src="/static/bootstrap/js/bootstrap.min.js" /script /body /html
Django form应用Bootstrap样式简单示例2、批量添加样式
可通过重写form类的init方法来实现。
class LoginForm(forms.Form): username = forms.CharField( min_length=8, label="用户名", initial="多多", error_messages={ "required": "不能为空", "invalid": "格式错误", "min_length": "用户名最短8位" ... def __init__(self, *args, **kwargs): super(LoginForm, self).__init__(*args, **kwargs) for field in iter(self.fields): self.fields[field].widget.attrs.update({ class: form-control })
批量添加样式
12214.html
cgojava相关文章
- Django(75)django-rest-framework-simplejwt「建议收藏」
- from django.db import models_独立团模块源码
- Django(9)url指定默认参数[通俗易懂]
- Django(54)drf视图家族「建议收藏」
- 基于Pycharm的Django学习1 —— Django三种响应
- Django菜鸟教程学习记录(一)
- Django 教程_最简单剪花朵的步骤
- django服务器_pycharm配置远程服务器解释器
- Django Ajax 实现历史图形查询
- Django 单元测试笔记
- Django自动化测试平台项目前端框架设计
- django csrf 验证问题及 csrf 原理
- Django REST Framework-视图的装饰器(一)
- Django REST Framework-配置路由
- Django REST Framework-过滤器(四)
- python3开发进阶-Django框架中form的查看校验方法is_valid()的源码,自定义验证方法详解编程语言
- Django Rest Framework源码剖析(五)—–解析器详解编程语言
- Django基础学习二详解编程语言
- 如何解决django配置settings时遇到Couldnotimportsettings'conf.local'