在我们写代码之前我们首先要知道Form是用来干什么的。
在我们提交数据的时候用的最多的就是form标签,在将数据提交给后端前,为了提高网站的运行速度,减去了错误的字段也提交到数据库这个时间,通过Form进行验证,只有符合的数据可以传送给数据库,在进行操作中实现的功能:生成了页面可用的HTML标签 对用户提交的数据进行验证(字段的功能) 通过对象保存上次输入的数据 ,下面我们就会介绍Form组件是怎样实现这些功能的。
urls.py
from django.contrib import admin
from django.urls import path
from app import views
urlpatterns = [
path('admin/', admin.site.urls),
path('verify/',views.verify)
]
models.py
from django.db import models
# Create your models here.
class UserInfo(models.Model):
user = models.CharField(max_length=32)
pwd = models.CharField(max_length=32)
email = models.EmailField(max_length=32)
views.py
在创建的Fm这个类中我们首先要梳理下他的功能:
[.*?]Filed : 出现这样的格式,代表的就是字段(例如:CharField),主要的功能是帮我们验证用户发过来的数据是否符合规范。
插件(widget):虽然我们在上面讲到字段本身是为了做验证,但是通过源码我们发现[.*?]Filed类继承的是Field类,在这个类中我们便可以发现有这个插件,主要的功能就是定义所生成的HTML标签,可以定义的标签如下:
__all__ = (
'Media', 'MediaDefiningClass', 'Widget', 'TextInput', 'NumberInput',
'EmailInput', 'URLInput', 'PasswordInput', 'HiddenInput',
'MultipleHiddenInput', 'FileInput', 'ClearableFileInput', 'Textarea',
'DateInput', 'DateTimeInput', 'TimeInput', 'CheckboxInput', 'Select',
'NullBooleanSelect', 'SelectMultiple', 'RadioSelect',
'CheckboxSelectMultiple', 'MultiWidget', 'SplitDateTimeWidget',
'SplitHiddenDateTimeWidget', 'SelectDateWidget',
)
#例如:widget = widgets.TextInput(attr={'class':'row'}) 意思就是在input标签中创建了一个名称row的class属性。
通过上面的介绍我们发现在使用字段是我们可以直接导入
from django.forms import fields
想要验证和定制插件的功能就在这个模块下面使用就可以了。
下面我们介绍obj.is_valid() 这个方法,我们首先要理解,在form对象中有很多个字段,在字段中我们可以进行验证和HTML的定制,而is_valid() 就是一直在循环form对象中的字段来进行验证。
那么现在还有一个问题就是 obj 传输回来的是个怎样的数据呢?
亲自测试了下返回的数据如下:
<tr><th><label for="id_user">User:</label></th><td><input type="text" name="user" value="root" class="sty" required id="id_user"></td></tr>
<tr><th><label for="id_pwd">Pwd:</label></th><td><ul class="errorlist"><li>密码长度太短</li></ul><input type="text" name="pwd" value="123" maxlength="12" minlength="4" required id="id_pwd"></td></tr>
<tr><th><label for="id_email">Email:</label></th><td><ul class="errorlist"><li>邮箱格式错误</li></ul><input type="email" name="email" value="1565556@12" required id="id_email"></td></tr>
<ul class="errorlist"><li>pwd<ul class="errorlist"><li>密码长度太短</li></ul></li><li>email<ul class="errorlist"><li>邮箱格式错误</li></ul></li></ul>
在Djngo2.26这个版本在内部的代码已经将数据封装的很好了。就是返回来HTML的格式。所以当用户所填数据不符合我们规定的格式时,只会提示错误的一行,会保存上一次输入的对象,也就是这个原理。
下面便是业务逻辑的代码:
from django.shortcuts import render
from app import models
from django import forms
from django.forms import widgets
from django.forms import fields
# Create your views here.
class Fm(forms.Form):
user = fields.CharField(error_messages={'required':'用户名不能为空'},
widget=widgets.TextInput(attrs={'class':'sty'})
)
pwd = fields.CharField(max_length=12,min_length=4,error_messages={'required':'密码不能为空','max_length':'密码长度过长','min_length':'密码长度太短'})
email = fields.EmailField(error_messages={'invalid':"邮箱格式错误",'required':'邮箱不能为空'})
def verify(request):
if request.method == 'GET':
obj = Fm()
return render(request,"verify.html",{'obj':obj})
elif request.method == 'POST':
print(request.POST)
obj = Fm(request.POST)
a = obj.is_valid()
if a:
print(obj.cleaned_data)
models.UserInfo.objects.create(**obj.cleaned_data)
else:
print(obj.errors)
return render(request,"verify.html",{'obj':obj})
return render(request,"verify.html")
verify.py
下面代码注释的部分就是通过form操作可以生成可用的HTML标签代码
源码例子 as_ul:可以在前端自动生成登陆框。
def as_ul(self):
"Return this form rendered as HTML <li>s -- excluding the <ul></ul>."
return self._html_output(
normal_row='<li%(html_class_attr)s>%(errors)s%(label)s %(field)s%(help_text)s</li>',
error_row='<li>%s</li>',
row_ender='</li>',
help_text_html=' <span class="helptext">%s</span>',
errors_on_separate_row=False,
)
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Login</title>
<link rel="stylesheet" href="/static/bootstrap.css">
<style>
</style>
</head>
<body>
<div class="container">
<form action="/verify/" method="post">
{% csrf_token %}
{# {{ obj.as_p }}#}
{# {{ obj.as_ul }}#}
{# <table>#}
{# {{ obj.as_table }}#}
{# </table>#}
<p>{{ obj.user }}{{ obj.errors.user.0 }} </p>
<p>{{ obj.pwd }}{{ obj.errors.pwd.0 }} </p>
<p>{{ obj.email }}{{ obj.errors.email.0 }} </p>
<input type="submit" class="btn btn-info" value="OK">
</form>
</div>
</body>
</html>
当输入不符合error_messages里面饿要求时的效果:
既然说好了一篇解决Form组件,这会就不停了。
下面介绍一些Form中的一些内置字段:
在查看源码我们可以找Filed中初始化代码的下面:
validators = [ ] : 书写规则 :
pwd = fields.CharField(
validators = [Regexvalidator(r'正则表达式','错误提示信息'),]
)
#Regexvalidator : 错误
class Filed:
required = True | 是否允许为空,高级浏览器自动补上 |
widget = None | 插件,自定制HTML标签 |
label = None | 用于生成Label标签 |
initial = None | 初始值是什么,在后面写初始值 |
help_text = ' ' | 提示信息 |
error_messages = None | 错误信息,上文介绍 |
show_hidden_initial = False | 创建并隐藏一个和已有标签一样的标签 |
validators = [ ] | 自定义一个正则表达式进行验证 |
localize = False | 是否支持本地化 |
disabled = False | 是否可以编辑 |
label_suffix = None | Label内容后缀,默认是":" |
在Field的内部还有:
ChaField 、 IntegerField 、 FloatField 、 DecimalField 、 BaseTemporalField 、 DateField 、 DurationField 、 RegexField 、 EmailField 、 FieldField 、 ImageField 等,它们的差别就是由于自定制的正则表达式不同,而作一些不同格式的验证。我们可以直接使用这个类,也可以自己 通过validators = [ ]进行创建。
所以上面的便不一一去写。
挑几个重要的:
class FileFiled:
allow_empty_file = False : 是否允许空文件
ChoiceField:
choices = () :用于选择的下拉框
required = True
widget = None
label = None
initial = None
help_text = ' '
使用格式:xxx = fields.(Multiple/radio等)ChoiceField(choices=[(0,'xx'),]) 在前端直接用{{obj.xxx}}就可以出现下拉框选择项
今天就先写到这,后面继续补充,希望可以帮到您!!!
see you again.