Form中添加自定义的验证:

   1.对特定字段属性的验证;

   2.包含多字段的验证.

先创建一个简单的Form:

from django import forms

class ContactForm(forms.Form):
subject = forms.CharField(max_length=100)
message = forms.CharField()
sender = forms.EmailField()
recipients = MultiEmailField()
cc_myself = forms.BooleanField(required=False)

1.验证特定字段属性

使用表单子类中的clean_<fieldname>()方法 -- 通过表单中的字段名称替换.这个方法完成特定属性相关的验证,这个验证与字段的类型无关.这个方法没有任何传入的参数.你需要查找self.cleaned_data中该字段的值,记住此时它已经是一个python对象而不是表单中提交的原始字符串(它位于cleaned_data中是因为字段clean()方法已经验证过一次数据).

例如,在ContactForm中,我们想确保recipients字段始终包含'fred@example.com'.这是特定于我们这个表单的验证,所以我们打算将它放在通用的MultiEmailField类中.编写一个运行在recipients字段上的验证方法:

from django import forms

class ContactForm(forms.Form):
#Everything as before
...
def clean_recipients(self):
data = self.cleaned_data['recipients']
if 'fred@example.com' not in data:
raise forms.ValidationError('You havev forgotten Fred!') # Always return a value to use as the new cleaned data, even if this method didn't change it
return data

2.验证相互依赖的字段

假设我们添加另外一个需求到联系人表单中:如果cc_myself字段为True,那么subject必须包含单词'help'.这个验证包含多个字段,所以表单clean()方法是个不错的地方.

注意,这里讨论的是表单clean()方法,上面有提到一个字段clean()方法.区别字段和表单之间的差别非常重要,字段是单个数据,表单是字段的集合.

在调用表单clean()方法的时候,所有字段的验证方法已经执行完,所以self.cleaned_data填充的是目前为止已经合法的数据.所以需要记住一个事实,你需要验证的字段可能没有通过初始的字段检查!

from django import forms

class ContactForm(forms.Form):
# Everything as before
...
def clean(self):
cleaned_data = super(ContactForm, self).clean()
cc_myself = cleaned_data.get('cc_myself')
subject = cleaned_data.get('subject') if cc_myself and subject:
# Only do something if both fields are valid so far.
if 'help' not in subject:
raise forms.ValidationError("Did not send for 'help' in the subject despite CC'ing yourself")

在这段代码中,如果抛出验证错误,表单将在表单的顶部显示(通常是)描述该问题的一个错误信息。

注意,示例代码中super(ContactForm, self).clean()的调用是为了保证维持父类中的验证逻辑。

3.多表单提交的外键处理

假设有多个模型之间存在外键关系,那么在同一个页面同时提交这几个表单的处理方法:

建立几个模型:

from django.db import models

class Store(models.Model):
... class Deport(models.Model):
s_name = models.ForeignKey(Store)
... class Address(models.Model):
s_name = models.ForeignKey(Store)
...

给这几个模型分别建立模型表单.

由于其中两个表使用了1个外键约束,如果同时提交和保存数据会导致数据表中的s_name_id字段值为NULL.为了解决这个问题,我们采用延迟提交给数据库的方式.

ModelForm的save()方法接受一个可选的commit关键字参数,其值为True/False.如果save()commit=False,那么它将返回一个还没保存到数据库的模型实例对象.这种情况下,你需要调用该返回的模型实例的save()方法.这样你可以在保存数据之前进行一些自定义的处理.commit默认为True.

from django.views.generic.base import View

class Store_Add(View):
...
def post(self, request):
sf = StoreForm(request.POST)
df = DeportForm(request.POST)
af = AddressForm(request.POST)
if sf.is_valid() and df.is_valid() and af.is_valid():
store = sf.save()
dform = df.save(commit=False) # 将来自DeportForm的数据暂存为一个模型实例,其中s_name字段为空
dform.s_name = store
dform.save()
aform = af.save(commit=False)
aform.s_name = store
aform.save()
...

4.从表单中访问字段

可以通过表单fields属性访问字段:

#models.py
from django.db import models class Publisher(models.Model):
name = models.CharField(max_length=30)
address = models.CharField(max_length=50)
website = models.URLField() def __str__(self):
return self.name #forms.py
from django import forms
from myapp.models import Publisher class PublisherForm(forms.ModelForm):
class Meta:
model = Publisher
fields = '__all__' >>> form = PublisherForm()
>>> form.fields
# 返回一个有序字典对象,键为Form中的字段名,值为fields对象
OrderedDict([('name', <django.forms.fields.CharField at 0x1d075ebca90>),
('address', <django.forms.fields.CharField at 0x1d075ebcb38>),
('website', <django.forms.fields.URLField at 0x1d07696cc18>)]) 可以使用字典的方法对Form的字段进行一些操作,例如:
form.fields.update({'website': forms.CharField(widget=forms.TextInput()}) 后者动态的对某一个字段的属性进行修改:
form.fields['website'].initial = self.request.user.website

fields对象的一些参数(属性)参考文档中的说明.



参考:http://python.usyiyi.cn/translate/django_182/ref/forms/validation.html#validating-fields-with-clean

   https://segmentfault.com/a/1190000007183873

Django Form表单学习总结的更多相关文章

  1. django form表单验证

    一. django form表单验证引入 有时时候我们需要使用get,post,put等方式在前台HTML页面提交一些数据到后台处理例 ; <!DOCTYPE html> <html ...

  2. Django(5) session登录注销、csrf及中间件自定义、django Form表单验证(非常好用)

    一.Django中默认支持Session,其内部提供了5种类型的Session供开发者使用: 数据库(默认) 缓存 文件 缓存+数据库 加密cookie 1.数据库Session 1 2 3 4 5 ...

  3. Django form表单 组件

    目录 Django form表单 组件 Form 组件介绍 普通方式手写注册功能 使用form组件实现注册功能 Form 常用字段与插件 常用字段(必备) 字段参数(必备) 内置验证(必备) 自定义效 ...

  4. Django学习笔记之Django Form表单详解

    知识预览 构建一个表单 在Django 中构建一个表单 Django Form 类详解 使用表单模板 回到顶部 构建一个表单 假设你想在你的网站上创建一个简单的表单,以获得用户的名字.你需要类似这样的 ...

  5. Django form表单

    Form介绍 之前在HTML页面中利用form表单向后端提交数据时,都会写一些获取用户输入的标签并且用form标签把它们包起来.与此同时我们在好多场景下都需要对用户的输入做校验,比如校验用户是否输入, ...

  6. Django Form表单组件

    Form介绍 我们之前在HTML页面中利用form表单向后端提交数据时,都会写一些获取用户输入的标签并且用form标签把它们包起来. 与此同时我们在好多场景下都需要对用户的输入做校验,比如校验用户是否 ...

  7. django Form 表单 总结与小实例

    开头寄语: 这几天一直在看Django的form表单验证,然后想对于这几天要有个总结. 首先,先来看一下找到的一个form表单验证的流程: 验证过程 流程详解1. 函数full_clean()依次调用 ...

  8. django Form表单的使用

    Form django表单系统中,所有的表单类都作为django.forms.Form的子类创建,包括ModelForm 关于django的表单系统,主要分两种 基于django.forms.Form ...

  9. python django Form表单

    Django 拥有自己独立的表单功能块,可以完成: 1.表单的定义 2.表单的校验 3.表单的前端样式 等功能,方便我们开发,那么接下来,我们看一下表单的定义 首先我们确定我们要编写的功能,一个提供给 ...

随机推荐

  1. Flask05 cookie

    1 什么是cookie 就是网站存放到你浏览器中的一部分固定内容:当你下次访问我这个网站的时候,你会把之前我存放到你浏览器中的数据带回来给我        你要先登录(用户名.密码) ->   ...

  2. MongoDB学习之路(四)

    MongoDB插入文档 MongoDB使用insert()或save()方法向集合中插入文档. db.COLLECTION_NAME.insert(document); For instance &g ...

  3. 201521123098 《Java程序设计》第9周学习总结

    1. 本周学习总结 1.1 以你喜欢的方式(思维导图或其他)归纳总结异常相关内容. 1. 在catch时需要考虑各个异常的继承关系,存在继承关系时需要先把子类异常的catch放在前面: 2. 当try ...

  4. Java第九周学习总结

    1. 本周学习总结 1.1 以你喜欢的方式(思维导图或其他)归纳总结异常相关内容. 2. 书面作业 本次PTA作业题集异常 1.常用异常 题目5-1 1.1 截图你的提交结果(出现学号) 1.2 自己 ...

  5. 201521123087 《Java程序设计》第11周学习总结

    1. 本周学习总结 2. 书面作业 本次PTA作业题集多线程 互斥访问与同步访问完成题集4-4(互斥访问)与4-5(同步访问)1.1 除了使用synchronized修饰方法实现互斥同步访问,还有什么 ...

  6. 【Socket编程】通过Socket实现UDP编程

    通过Socket实现UDP编程 UDP通信: 1.UDP协议(用户数据报协议)是无连接.不可靠.无序的. 2.UDP协议以数据报作为数据传输的载体. 3.使用UDP进行数据传输时,首先需要将要传输的数 ...

  7. Thrift教程初级篇——thrift安装环境变量配置第一个实例

    前言: 因为项目需要跨语言,c++客户端,web服务端,远程调用等需求,所以用到了RPC框架Thrift,刚开始有点虚,第一次接触RPC框架,后来没想到Thrift开发方便上手快,而且性能和稳定性也不 ...

  8. 支付宝支付php的demo或sdk报错 Warning: openssl_sign() [function.openssl-sign]: Unknown signature algorithm. in

    最近在做支付宝支付,在本地测试一切正常,上传到服务器就遇到报错: Warning: openssl_sign() [function.openssl-sign]: Unknown signature ...

  9. java使用POI操作XWPFDocument 生成Word实战(一)

    注:我使用的word 2016功能简介:(1)使用jsoup解析html得到我用来生成word的文本(这个你们可以忽略)(2)生成word.设置页边距.设置页脚(页码),设置页码(文本) 一.解析ht ...

  10. weblogic服务器上类或者方法找不到的解决办法

    下面以eclipse-birt(报表)为例,介绍这种问题出现的原因以及解决之道: 分析比较好的见:http://developer.actuate.com/community/forum/index. ...