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. UX是什么?

    UX(用户体验),操作过安卓手机或者苹果手机的系统吧?那么操作过程的整体体验就叫UX,而操作过程中所看到的界面颜色啦,图案,字体大小啦等等都属于UI设计,而交互设计(Interaction Desig ...

  2. 第五次作业2、请将该code进行代码重构,使之模块化,并易于阅读和维护;

    1.请运行下面code,指出其功能: (需附运行结果截图,并用简短文字描述其功能) 显示了人的姓名.年龄 2.请将该code进行代码重构,使之模块化,并易于阅读和维护: 3.观看视频The Exper ...

  3. 201521123115《Java程序设计》第6周学习总结

    1. 本周学习总结 1.1 面向对象学习暂告一段落,请使用思维导图,以封装.继承.多态为核心概念画一张思维导图,对面向对象思想进行一个总结. 注1:关键词与内容不求多,但概念之间的联系要清晰,内容覆盖 ...

  4. 201521123029《java程序设计》第2周学习总结

    1. 本周学习总结 (1)完成了课后习题,对所学知识进一步巩固. (2)学会了JAVA中的选择结构,循环结构,其中条件必须为布尔表达式,与C++非0即真不同. (3)学会java中的break和con ...

  5. 201521123078 《Java程序设计》第14周学习总结

    1. 本周学习总结 2. 书面作业 1. MySQL数据库基本操作 建立数据库,将自己的姓名.学号作为一条记录插入.(截图,需出现自己的学号.姓名) 在自己建立的数据库上执行常见SQL语句(截图) 2 ...

  6. Java课程设计 学生基本信息管理系统 团队博客

    学生基本信息管理系统团队博客 项目git地址 https://git.oschina.net/Java_goddess/kechengsheji 项目git提交记录截图 项目功能架构图与主要功能流程图 ...

  7. 201521123039 《java程序设计》第一周学习总结

    #1.本章学习总结 Java是面向对象的程序语言,它一切定义都是对象.我们所编写的Java程序经过编译后生成了*.class的文件,再经过JVM对*.class解释运行就可以得到Java程序,所以Ja ...

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

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

  9. 《MySQL必知必会》[03] 表数据的增删改

    1.增:插入数据 INSERT关键字可以插入新的行到数据库表中: 插入完整的行 插入行的一部分 插入多行 插入某些查询的结果 基本的INSERT语句是: INSERT INTO R(A1, A2, . ...

  10. Eclipse读取含有extjs的项目文件时卡死或者编写ExtJS时卡

    新建一个Eclipse或MyEclipse项目时,关掉验证. 项目右键-->Properties-->Builders--> 不勾选(JavaScript Validator.Val ...