django Form组件

django Form组件

Django的Form主要具有一下几大功能:

  • 生成HTML标签
  • 验证用户数据(显示错误信息)
  • HTML Form提交保留上次提交数据
  • 初始化页面显示内容

小试牛刀

1、创建Form类

from django.forms import Form
from django.forms import widgets  #插件 
from django.forms import fieldsclass MyForm(Form):user = fields.CharField(widget=widgets.TextInput(attrs={'id': 'i1', 'class': 'c1'}))gender = fields.ChoiceField(      #单选choices=((1, '男'), (2, '女'),),initial=2,widget=widgets.RadioSelect)city = fields.CharField(initial=2,widget=widgets.Select(choices=((1,'上海'),(2,'北京'),)))pwd = fields.CharField(widget=widgets.PasswordInput(attrs={'class': 'c1'}, render_value=True))

2、views函数处理

from django.shortcuts import render, redirect
from .forms import MyFormdef index(request):if request.method == "GET":obj = MyForm()return render(request, 'index.html', {'form': obj})elif request.method == "POST":obj = MyForm(request.POST, request.FILES)if obj.is_valid():values = obj.clean()print(values)else:errors = obj.errorsprint(errors)return render(request, 'index.html', {'form': obj})else:return redirect('http://www.google.com')

3、生成HTML 

<form action="/" method="POST" enctype="multipart/form-data"> #上传文件特殊的方法<p>{{ form.user }} {{ form.user.errors }}</p><p>{{ form.gender }} {{ form.gender.errors }}</p><p>{{ form.city }} {{ form.city.errors }}</p><p>{{ form.pwd }} {{ form.pwd.errors }}</p><input type="submit"/>
</form> 
<form method="POST" enctype="multipart/form-data">{% csrf_token %}{{ form.xxoo.label }}{{ form.xxoo.id_for_label }}{{ form.xxoo.label_tag }}{{ form.xxoo.errors }}<p>{{ form.user }} {{ form.user.errors }}</p><input type="submit" /></form>

From类  

创建Form类时,主要涉及到 【字段】 和 【插件】,字段用于对用户请求数据的验证,插件用于自动生成HTML; 

1、Django内置字段如下:

Fieldrequired=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内容后缀CharField(Field)max_length=None,             最大长度min_length=None,             最小长度strip=True                   是否移除用户输入空白IntegerField(Field)max_value=None,              最大值min_value=None,              最小值FloatField(IntegerField)...DecimalField(IntegerField)max_value=None,              最大值min_value=None,              最小值max_digits=None,             总长度decimal_places=None,         小数位长度BaseTemporalField(Field)input_formats=None          时间格式化   DateField(BaseTemporalField)    格式:2015-09-01
TimeField(BaseTemporalField)    格式:11:12
DateTimeField(BaseTemporalField)格式:2015-09-01 11:12DurationField(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)...BooleanField(Field)  ...NullBooleanField(BooleanField)...ChoiceField(Field)...choices=(),                选项,如:choices = ((0,'上海'),(1,'北京'),)required=True,             是否必填widget=None,               插件,默认select插件label=None,                Label内容initial=None,              初始值help_text='',              帮助提示ModelChoiceField(ChoiceField)...                        django.forms.models.ModelChoiceFieldqueryset,                  # 查询数据库中的数据empty_label="---------",   # 默认空显示内容to_field_name=None,        # HTML中value的值对应的字段limit_choices_to=None      # ModelForm中对queryset二次筛选ModelMultipleChoiceField(ModelChoiceField)...                        django.forms.models.ModelMultipleChoiceFieldTypedChoiceField(ChoiceField)coerce = lambda val: val   对选中的值进行一次转换empty_value= ''            空值的默认值MultipleChoiceField(ChoiceField)...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=''GenericIPAddressFieldprotocol='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类型...

注:UUID是根据MAC以及当前时间等创建的不重复的随机字符串

>>> import uuid# make a UUID based on the host ID and current time>>> uuid.uuid1()    # doctest: +SKIPUUID('a8098c1a-f86e-11da-bd1a-00112444be1e')# make a UUID using an MD5 hash of a namespace UUID and a name>>> uuid.uuid3(uuid.NAMESPACE_DNS, 'python.org')UUID('6fa459ea-ee8a-3ca4-894e-db77e160355e')# make a random UUID>>> uuid.uuid4()    # doctest: +SKIPUUID('16fd2706-8baf-433b-82eb-8c7fada847da')# make a UUID using a SHA-1 hash of a namespace UUID and a name>>> uuid.uuid5(uuid.NAMESPACE_DNS, 'python.org')UUID('886313e1-3b8a-5372-9b90-0c9aee199e5d')# make a UUID from a string of hex digits (braces and hyphens ignored)>>> x = uuid.UUID('{00010203-0405-0607-0809-0a0b0c0d0e0f}')# convert a UUID to a string of hex digits in standard form>>> str(x)'00010203-0405-0607-0809-0a0b0c0d0e0f'# get the raw 16 bytes of the UUID>>> x.bytesb'\x00\x01\x02\x03\x04\x05\x06\x07\x08\t\n\x0b\x0c\r\x0e\x0f'# make a UUID from a 16-byte string>>> uuid.UUID(bytes=x.bytes)UUID('00010203-0405-0607-0809-0a0b0c0d0e0f')
View Code

2、Django内置插件:  

TextInput(Input)
NumberInput(TextInput)
EmailInput(TextInput)
URLInput(TextInput)
PasswordInput(TextInput)
HiddenInput(TextInput)
Textarea(Widget)
DateInput(DateTimeBaseInput)
DateTimeInput(DateTimeBaseInput)
TimeInput(DateTimeBaseInput)
CheckboxInput
Select
NullBooleanSelect
SelectMultiple
RadioSelect
CheckboxSelectMultiple
FileInput
ClearableFileInput
MultipleHiddenInput
SplitDateTimeWidget
SplitHiddenDateTimeWidget
SelectDateWidget

常用选择插件

# 单radio,值为字符串
# user = fields.CharField(
#     initial=2,
#     widget=widgets.RadioSelect(choices=((1,'上海'),(2,'北京'),))
# )# 单radio,值为字符串
# user = fields.ChoiceField(
#     choices=((1, '上海'), (2, '北京'),),
#     initial=2,
#     widget=widgets.RadioSelect
# )# 单select,值为字符串
# user = fields.CharField(
#     initial=2,
#     widget=widgets.Select(choices=((1,'上海'),(2,'北京'),))
# )# 单select,值为字符串
# user = fields.ChoiceField(
#     choices=((1, '上海'), (2, '北京'),),
#     initial=2,
#     widget=widgets.Select
# )# 多选select,值为列表
# user = fields.MultipleChoiceField(
#     choices=((1,'上海'),(2,'北京'),),
#     initial=[1,],
#     widget=widgets.SelectMultiple
# )# 单checkbox
# user = fields.CharField(
#     widget=widgets.CheckboxInput()
# )# 多选checkbox,值为列表
# user = fields.MultipleChoiceField(
#     initial=[2, ],
#     choices=((1, '上海'), (2, '北京'),),
#     widget=widgets.CheckboxSelectMultiple
# )

在使用选择标签时,需要注意choices的选项可以从数据库中获取,但是由于是静态字段 ***获取的值无法实时更新***,那么需要自定义构造方法从而达到此目的。

方式一:

class TeacherFrom(Form):tname=fields.CharField(min_length=2)xx=fields.MultipleChoiceField(  #多选框用MultipleChoiceField# choices=models.Classes.objects.values_list("id","title"),widget=widgets.SelectMultiple)    #多选框def __init__(self,*args,**kwargs):   #修复一个小bug,定义一个init方法,继承TeacherTrom的内容,#构造自己都有的方法,每次实例化出来的对象。super(TeacherFrom,self).__init__(*args,**kwargs)self.fields['xx'].choices=models.Classes.objects.values_list("id","title")

方式二:

使用django提供的ModelChoiceField和ModelMultipleChoiceField字段来实现

from django import forms
from django.forms import fields
from django.forms import widgets
from django.forms import models as form_model
from django.core.exceptions import ValidationError
from django.core.validators import RegexValidatorclass FInfo(forms.Form):authors = form_model.ModelMultipleChoiceField(queryset=models.NNewType.objects.all())# authors = form_model.ModelChoiceField(queryset=models.NNewType.objects.all())

自定义验证规则

方式一:

from django.forms import Form
from django.forms import widgets
from django.forms import fields
from django.core.validators import RegexValidatorclass 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个字符'}))# 使用自定义验证规则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'邮箱'}))

方法三:自定义方法

from django import formsfrom django.forms import fieldsfrom django.forms import widgetsfrom django.core.exceptions import ValidationErrorfrom django.core.validators import RegexValidatorclass FInfo(forms.Form):username = fields.CharField(max_length=5,validators=[RegexValidator(r'^[0-9]+$', 'Enter a valid extension.', 'invalid')], )email = fields.EmailField()def clean_username(self):"""Form中字段中定义的格式匹配完之后,执行此方法进行验证:return:"""value = self.cleaned_data['username']if "666" in value:raise ValidationError('666已经被玩烂了...', 'invalid')return value

方式四:同时生成多个标签进行验证

from django.forms import Form
from django.forms import widgets
from django.forms import fieldsfrom django.core.validators import RegexValidator############## 自定义字段 ##############
class PhoneField(fields.MultiValueField):def __init__(self, *args, **kwargs):# Define one message for all fields.error_messages = {'incomplete': 'Enter a country calling code and a phone number.',}# Or define a different message for each field.f = (fields.CharField(error_messages={'incomplete': 'Enter a country calling code.'},validators=[RegexValidator(r'^[0-9]+$', 'Enter a valid country calling code.'),],),fields.CharField(error_messages={'incomplete': 'Enter a phone number.'},validators=[RegexValidator(r'^[0-9]+$', 'Enter a valid phone number.')],),fields.CharField(validators=[RegexValidator(r'^[0-9]+$', 'Enter a valid extension.')],required=False,),)super(PhoneField, self).__init__(error_messages=error_messages, fields=f, require_all_fields=False, *args,**kwargs)def compress(self, data_list):"""当用户验证都通过后,该值返回给用户:param data_list::return:"""return data_list############## 自定义插件 ##############
class SplitPhoneWidget(widgets.MultiWidget):def __init__(self):ws = (widgets.TextInput(),widgets.TextInput(),widgets.TextInput(),)super(SplitPhoneWidget, self).__init__(ws)def decompress(self, value):"""处理初始值,当初始值initial不是列表时,调用该方法:param value::return:"""if value:return value.split(',')return [None, None, None]

初始化数据

在Web应用程序中开发编写功能时,时常用到获取数据库中的数据并将值初始化在HTML中的标签上。

1、Form  

from django.forms import Form
from django.forms import widgets
from django.forms import fields
from django.core.validators import RegexValidatorclass MyForm(Form):user = fields.CharField()city = fields.ChoiceField(choices=((1, '上海'), (2, '北京'),),widget=widgets.Select)

2、Views  

from django.shortcuts import render, redirect
from .forms import MyFormdef index(request):if request.method == "GET":values = {'user': 'root', 'city': 2}obj = MyForm(values)return render(request, 'index.html', {'form': obj})elif request.method == "POST":return redirect('http://www.google.com')else:return redirect('http://www.google.com')

3、HTML  

<form method="POST" enctype="multipart/form-data">{% csrf_token %}<p>{{ form.user }} {{ form.user.errors }}</p><p>{{ form.city }} {{ form.city.errors }}</p><input type="submit"/>
</form>

is_valid 内部原理

  #is_valid  内部原理"""1.LoginForm实例化时,self.fields={              #self.fields是一个子典的格式 key是每个字段'user':正则表达式'pwd':正则表达式}2.循环self.fieldsflag=Trueerrorscleaned_datafor k,v in self.fields.items():#1.user,正则表达式input_value = request.POST.get(k)正则表达式和input_valueflag = False:return flag    #返回错误信息"""
class LoginForm(Form):user=fields.CharField(max_length=16,min_length=6,required=True,error_messages={'request':'用户名不能为空','max_length=16':'用户名不能过长','min_length=6':'用户名不能太短',})pwd=fields.CharField(min_length=8,required=True)def login(request):if request.method == "GET":return render(request,'login.html')else:obj=LoginForm(request.POST)#is_valid  内部原理"""1.LoginForm实例化时,self.fields={              #self.fields是一个子典的格式 key是每个字段'user':正则表达式'pwd':正则表达式}2.循环self.fieldsflag=Trueerrorscleaned_datafor k,v in self.fields.items():#1.user,正则表达式input_value = request.POST.get(k)正则表达式和input_valueflag = False:return flag    #返回错误信息"""if obj.is_valid():print(obj.cleaned_data)return redirect('http://www.baidu.com')else:print(obj.errors)return render(request,'login.html',{'obj':obj})
View Code

 

转载于:https://www.cnblogs.com/niejinmei/p/7126704.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/268998.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

RUP大讲堂(第三讲):如何建立软件产品的愿景

我撰写的一些关于RUP的讲义&#xff0c;PDF格式&#xff0c;可在文后点击“附件下载”阅读全文。本篇内容简介及部分截图&#xff1a;◇ 为什么需要愿景◇ 业务愿景◇ 系统愿景◇ 导出愿景的技巧◇ 小结

光纤测试时不得不用的福禄克CFP光纤测试仪

不同的光纤应用具有不同的最大插入损耗要求&#xff0c;以确保损耗不会过高&#xff0c;从而防止信号正确到达远端。因此&#xff0c;第一项任务涉及确定系统上线时客户计划运行的光纤应用程序&#xff0c;以及他们将来计划运行的光纤应用程序。 假设您的客户正在设计一个数据…

java怎么表示正无穷大_有什么比无穷大更大,比无穷小更小?

你好&#xff0c;欢迎来到我的《数学通识50讲》。我们讲无穷大是比任何数都大&#xff0c;那么世界上只有一个无穷大吗&#xff1f;如果有多个&#xff0c;能比较大小吗&#xff1f;类似的&#xff0c;无穷小就是无限接近于零&#xff0c;那么世界上会有不同的无穷小么&#xf…

越用越快的福禄克布线认证测试仪

对一些人来说&#xff0c;福禄克网络推出的布线认证测试仪系列仿佛就在昨天&#xff0c;特别是那些仍然坚持使用已经停产的福禄克DTX系列测试仪的用户。 但信不信由你&#xff0c;现在是包括DSX系列的测试仪在内的VersionV测试仪和光纤测试仪Pro和CFP光纤测试仪专业认证测试人员…

日照油库系统推荐_战“疫”快报(3.21)| 油库三期工程罐基础混凝土浇筑全部完成...

“3月20日&#xff0c;油库三期工程罐基础混凝土浇筑施工全部完成&#xff0c;为确保油库三期工程整体工期奠定了坚实基础。”“海通公司“日照—韩国平泽”航线恢复每周三班运营。海通公司在持续抓好疫情防控同时&#xff0c;保障腹地企业复工复产&#xff0c;精心组织航线运行…

vm+ubuntu联网

在vm下刚装了ubuntu&#xff0c;就是上不了网&#xff0c;确认以下配置后方可以 1、我的电脑开机自动把VM的相关服务都关闭了&#xff0c;需要手动打开 在控制面板中搜索服务&#xff0c;手动启动vm服务 2、在适配器里启用vm网卡 3、使用桥接模式 转载于:https://www.cnblogs.c…

网络布线工程师科普铜缆光纤损耗那点事!

&#xff08;1&#xff09;插入损耗 什么是插入损耗&#xff1f; 插入损耗是信号沿电缆链路传输时损失的能量量。对于任何类型的传输&#xff0c;无论是电力传输还是数据传输&#xff0c;这都是一种自然现象。这种信号的减少&#xff0c;也称为衰减&#xff0c;与电缆长度直接…

一个本地分支能关联两个远程仓库吗_使用git分支保存hexo博客源码到github

hexo是当前最火的静态博客框架&#xff0c;支持Markdown格式文章编辑并自动生成对应的静态网页&#xff0c;简单高效令人爱不释手。使用hexo写博客的流程通常是&#xff0c;通过hexo new post_name命令&#xff0c;会自动在source/_post目录下生成一个待写的post_name.md文件编…

git的入门摸索和入门研究

git官网&#xff1a;https://git-scm.com/ git教程---菜鸟教程&#xff1a;http://www.runoob.com/git/git-tutorial.html git教程---廖雪峰&#xff1a;http://www.liaoxuefeng.com/wiki/0013739516305929606dd18361248578c67b8067c8c017b000/ git视频教程---极客学院&#xf…

您的光纤电缆和测试仪是否准备好用于400G以太网?

在大型超规模和云数据中心提供商的推动下&#xff0c;信令和收发器技术的进步推动了下一代传输速度的发展。现在&#xff0c;通过多模和单模光纤的400G以太网应用有多种选择&#xff0c;更多选项即将推出。国外的谷歌、Facebook和微软等大公司正在推动创新&#xff0c;以支持80…

网络游戏测试过程

游戏测试起因近几年来&#xff0c;网络游戏成了网络最新的弄潮儿&#xff0c;从盛大之传奇般的掘起&#xff0c;吸引了无数公司的眼球。但由于随着玩家的品位的升高&#xff0c;代理费用的上升&#xff0c;单一的代理国外游戏的模式已经很难在国内立足&#xff0c;而有中国传统…

org.mybatis.spring.MyBatisSystemException: nested exception is org.apache.ibatis.type.TypeException:

解决&#xff1a; 1 在SQL语句中使用#{name,jdbcTypeVARCHAR} ​指定JDBC类型 错误的&#xff1a; 修改后的&#xff1a;

uni中动态加载class_Java基础·类加载、反射

原文&#xff1a;Java基础类加载、反射 - 掘金 作者&#xff1a;宸道移动安全团队15.1 类的加载概述当程序要使用某个类时&#xff0c;如果该类还未被加载到内存中&#xff0c;则系统会通过加载、连接、初始化三步来实现对这个类进行初始化。1.加载&#xff1a;是将class文件读…

mysql 安装目录说明

转载于:https://www.cnblogs.com/xiluhua/p/7137663.html

如何测试光纤系统中的插入损耗

由于插入损耗是影响光纤链路支持给应用能力的主要性能参数&#xff0c;因此根据行业标准&#xff0c;光纤认证测试需要插入损耗。像福禄克网络的CFP光纤测试仪这样的光损耗测试集&#xff0c;通过在一端使用光源&#xff0c;在另一端使用功率计精确测量从另一端发出的光的数量&…

oracle脚本

监控Oracle数据库的常用shell脚本 作者: 出处:uml.org.cn ( 22 ) 砖 ( 33 ) 好 评论 ( 0 ) 条  进入论坛 更新时间&#xff1a;2006-01-25 10:25关 键 词&#xff1a;Oracle shell阅读提示&#xff1a;这篇文章介绍了DBA每天在监控Oracle数据库方面的职责&#xff0c;讲述…

设计模式之观察者模式demo

代码 public class WeatherData {private float temperature;private float pressure;private float humidity;//聚合private CurrentConditions currentConditions;public WeatherData(CurrentConditions currentConditions) {this.currentConditions currentConditions;}pu…