Django Form表单学习总结
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表单学习总结的更多相关文章
- django form表单验证
一. django form表单验证引入 有时时候我们需要使用get,post,put等方式在前台HTML页面提交一些数据到后台处理例 ; <!DOCTYPE html> <html ...
- Django(5) session登录注销、csrf及中间件自定义、django Form表单验证(非常好用)
一.Django中默认支持Session,其内部提供了5种类型的Session供开发者使用: 数据库(默认) 缓存 文件 缓存+数据库 加密cookie 1.数据库Session 1 2 3 4 5 ...
- Django form表单 组件
目录 Django form表单 组件 Form 组件介绍 普通方式手写注册功能 使用form组件实现注册功能 Form 常用字段与插件 常用字段(必备) 字段参数(必备) 内置验证(必备) 自定义效 ...
- Django学习笔记之Django Form表单详解
知识预览 构建一个表单 在Django 中构建一个表单 Django Form 类详解 使用表单模板 回到顶部 构建一个表单 假设你想在你的网站上创建一个简单的表单,以获得用户的名字.你需要类似这样的 ...
- Django form表单
Form介绍 之前在HTML页面中利用form表单向后端提交数据时,都会写一些获取用户输入的标签并且用form标签把它们包起来.与此同时我们在好多场景下都需要对用户的输入做校验,比如校验用户是否输入, ...
- Django Form表单组件
Form介绍 我们之前在HTML页面中利用form表单向后端提交数据时,都会写一些获取用户输入的标签并且用form标签把它们包起来. 与此同时我们在好多场景下都需要对用户的输入做校验,比如校验用户是否 ...
- django Form 表单 总结与小实例
开头寄语: 这几天一直在看Django的form表单验证,然后想对于这几天要有个总结. 首先,先来看一下找到的一个form表单验证的流程: 验证过程 流程详解1. 函数full_clean()依次调用 ...
- django Form表单的使用
Form django表单系统中,所有的表单类都作为django.forms.Form的子类创建,包括ModelForm 关于django的表单系统,主要分两种 基于django.forms.Form ...
- python django Form表单
Django 拥有自己独立的表单功能块,可以完成: 1.表单的定义 2.表单的校验 3.表单的前端样式 等功能,方便我们开发,那么接下来,我们看一下表单的定义 首先我们确定我们要编写的功能,一个提供给 ...
随机推荐
- 避免subList/subString陷阱
避免subList/subString陷阱 java.util.List 接口提供了一个实例方法 List<E> subList(int fromIndex, int toIndex), ...
- 软工+C(2017第2期) 分数和checklist
// 上一篇:题目设计.点评和评分 // 下一篇:超链接 教学里,建立清晰明确的评分规则并且一开始就公布,对于教师.助教.学生都是重要的. 公布时机 在课程开始的时候,就需要确定并公布评分机制,随着课 ...
- 【Beta阶段】第六次scrum meeting
Coding/OSChina 地址 1. 会议内容 学号 主要负责的方向 昨日任务 昨日任务完成进度 接下去要做 99 PM 着手联网功能 100% 配合100完成联网功能 100 DEV 完善服务器 ...
- 201521123010 《Java程序设计》第8周学习总结
1. 本周学习总结 1.1 以你喜欢的方式(思维导图或其他)归纳总结集合与泛型相关内容. 2. 书面作业 本次作业题集集合 ①List中指定元素的删除(题目4-1) 1.1 实验总结 A: 这道题是老 ...
- 201521123099 《Java程序设计》第6周学习总结
1. 本周学习总结 1.1 面向对象学习暂告一段落,请使用思维导图,以封装.继承.多态为核心概念画一张思维导图,对面向对象思想进行一个总结. 注1:关键词与内容不求多,但概念之间的联系要清晰,内容覆盖 ...
- 201521123054 《Java程序设计》第14周学习总结
1. 本周学习总结 2. 书面作业 1. MySQL数据库基本操作 1.1建立数据库,将自己的姓名.学号作为一条记录插入.(截图,需出现自己的学号.姓名) 1.2在自己建立的数据库上执行常见SQL语句 ...
- pl/sql developer 连接服务器上的数据库
1, 在本地安装的Oracle中找到目录 oracle\product\11.2.0\dbhome_1\network\admin, 它下面一般有两个文件可以进行编辑tnsnames.ora li ...
- 如何在Oracle官网下载历史版本JDK
打开Oracle官网,准备下载java JDK(下载时需要使用注册用户登陆,可以免费注册) 官网地址:http://www.oracle.com/ 2 鼠标悬停Downloads,会出现相关内容,如下 ...
- Eclipse 多行复制并且移动失效
Eclipse 有个好用的快捷键 即 多行复制 并且移动 但是 用 Win7 的 电脑 的 时候 发现屏幕 在 旋转 解决方案: 打开Intel的显卡控制中心 把旋转 的 快捷键 进行更改 就好 ...
- OC——关于KVC
我们知道在C#中可以通过反射读写一个对象的属性,有时候这种方式特别方便,因为你可以利用字符串的方式去动态控制一个对象.其实由于ObjC的语言特性,你根部不必进行任何操作就可以进行属性的动态读写,这种方 ...