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. 【Java并发编程】之六:Runnable和Thread实现多线程的区别(含代码)

    转载请注明出处:http://blog.csdn.net/ns_code/article/details/17161237 Java中实现多线程有两种方法:继承Thread类.实现Runnable接口 ...

  2. 201521123040《Java程序设计》第5周学习总结

    1. 本周学习总结 1.1 尝试使用思维导图总结有关多态与接口的知识点. 2. 书面作业 1.代码阅读:Child压缩包内源代码 1.1 com.parent包中Child.java文件能否编译通过? ...

  3. 201521123067 《Java程序设计》第11周学习总结

    201521123067 <Java程序设计>第11周学习总结 1. 本周学习总结 1.1 以你喜欢的方式(思维导图或其他)归纳总结多线程相关内容. 2. 书面作业 本次PTA作业题集多线 ...

  4. 201521123012 《Java程序设计》第十二周学习总结

     作业参考文件 1. 本周学习总结 1.1 以你喜欢的方式(思维导图或其他)归纳总结多线程相关内容. 2. 书面作业 将Student对象(属性:int id, String name,int ag ...

  5. java课程设计-表达式运算(团队博客)

    1 团队课程设计博客 1 团队名称.团队成员介绍 团队名称 奔跑吧土拨鼠 团队成员 洪亚文 201521123065 网络1513 郑晓丽 201521123066 网络1513 2 项目git地址 ...

  6. linux c函数指针的应用

    头文件:1.h #include<stdio.h> int nul_func(); int test1(int a,int b); int test2(int a,int b,int c) ...

  7. Java I/O 从0到1 - 第Ⅰ滴血 File

    前言 File 类的介绍主要会依据<Java 编程思想>以及官网API .相信大家在日常工作中,肯定会遇到文件流的读取等操作,但是在搜索过程中,并没有找到一个介绍的很简洁明了的文章.因此, ...

  8. Eclipse插件springsource-tool-suite在线和离线安装步骤

    springsource-tool-suite插件是一个基于Eclipse的开发环境,为开发Spring应用程序而定制.它提供了一个即用的环境来实现,调试,运行和部署Spring应用程序,包括Pivo ...

  9. FoxOne---一个快速高效的BS框架--数据访问(Dao)

    FoxOne---一个快速高效的BS框架--(1) FoxOne---一个快速高效的BS框架--(2) FoxOne---一个快速高效的BS框架--(3) FoxOne---一个快速高效的BS框架-- ...

  10. 简易RPC框架-私有协议栈

    *:first-child { margin-top: 0 !important; } body > *:last-child { margin-bottom: 0 !important; } ...