文档章节

Django的Form机制详解

好2138
 好2138
发布于 2014/01/09 10:32
字数 514
阅读 89
收藏 0

环境:Python 2.7.5 + Django 1.6
使用Django,我们可以以声明式的方式来定义一个Form,如下:
# -*- coding: utf-8 -*-
from django import forms
class SimpleForm(forms.Form):

    field_a = forms.CharField(max_length=100)
    field_b = forms.CharField(max_length=100)
写起来很舒服,但是问题来了,当我把这个Form初始化之后,比如:

from polls.forms import SimpleForm
sf = SimpleForm({'field_a':'value of field_a', 'field_b':'value of field_b'})
然后在python shell里执行dir(sf),发现该实例并没有field_a和field_b这两个属性,显然我们就不能像sf.field_a这么来引用sf上的字段了。可是明明我们可以在template里以{{ form_name.field_name }}的形式来引用form的字段,这是怎么回事呢?

一番调查之后发现背后的实现机制还比较曲折。首先,如果我们要引用form里的字段应该怎么写呢?应该这么写:sf['field_a']

Python教程 http://www.iplaypython.com/

为什么要这么写呢?上代码,django.forms.BaseForm的__getitem__方法:

def __getitem__(self, name):
    "Returns a BoundField with the given name."
    try:
        field = self.fields[name]
    except KeyError:
        raise KeyError('Key %r not found in Form' % name)
return BoundField(self, field, name)
#更多关于Django的内容,玩蛇网的Python培训课程中会讲解到。

这样就把BaseForm变成一个像dict一样的的容器了,所以可以用上面的语法来引用form里的字段。

新的问题又来了,为什么可以在template里以{{ form_name.field_name }}的形式来引用form的字段呢?见Django的官方文档:https://docs.djangoproject.com/en/1.6/topics/templates/#variables。原来Django的模板引擎碰到{{ form_name.field_name }}这样的表达式,会在form_name对象上运行字典查找,所以模板引擎对{{ sf.field_a }}求值时实际上运行了sf['field_a'],真相大白了。

    另外,上文中的SimpleForm的类型实际上是django.forms.DeclarativeFieldsMetaclass。这个元类实际上是把SimpleForm中以声明式语法声明的所有字段(还包括父类中的声明式字段)通过get_declared_fields方法转换成了一个dict,并将dict的值赋给了将要生成的类的base_fields属性,然后基于SimpleForm生成了一个新的类。

© 著作权归作者所有

共有 人打赏支持
好2138
粉丝 1
博文 10
码字总数 4484
作品 0
梅州
私信 提问
Django Form 详解

构建1个表单: 1、新建1个 forms.py 模块,并导入 django.forms 模块 2、在 forms.py 模块中定义1个 form 类,和 moldes 类 相似 3、在 views.py 导入forms.py模块, 并实例化1个 form 表单对...

明月知心
2016/12/23
65
0
详解Django的CSRF认证

1.csrf原理 2.Django中的CSRF中间件 首先,我们知道Django中间件作用于整个项目。 在一个项目中,如果想对全局所有视图函数或视图类起作用时,就可以在中间件中实现,比如想实现用户登录判断...

任平生78
10/08
0
0
小司机带你学: Django+Xadmin打造在线教育平台[Python2&3通用 ](六)4-10

6-4 用form实现登录-1 上面我们的用户登录的方法是基于函数来做的。本节我们做一个基于类方法的版本。 要求对类的继承有了解。 基础教程中基本上都是基于函数来做的,其实更推荐基于类来做。...

天涯明月笙
01/22
0
0
知识详解4:django之models与数据表

1.前言 上文中我们在views中的传递了一个字典,然后在templates中显示了出来,在实际的操作中不可能都这么传递数据,这里就需要用到数据库。第一节时我们创建django项目时,默认生成了一个s...

fuckCoding
2017/11/06
0
0
Cookie-Form型CSRF防御机制的不足与反思

Cookie-Form型CSRF防御机制的不足与反思 离别歌2016-09-2650 阅读 cookieformcsrf 今天看了 https://hackerone.com/reports/26647 有感。这个漏洞很漂亮,另外让我联想到很多之前自己挖过的漏...

离别歌
2016/09/26
0
0

没有更多内容

加载失败,请刷新页面

加载更多

大数据教程(9.5)用MR实现sql中的jion逻辑

上一篇博客讲解了使用jar -jar的方式来运行提交MR程序,以及通过修改YarnRunner的源码来实现MR的windows开发环境提交到集群的方式。本篇博主将分享sql中常见的join操作。 一、需求 订单数据表...

em_aaron
10分钟前
0
0
十万个为什么之什么是resultful规范

起源 越来越多的人开始意识到,网站即软件,而且是一种新型的软件。这种"互联网软件"采用客户端/服务器模式,建立在分布式体系上,通过互联网通信,具有高延时(high latency)、高并发等特点...

尾生
16分钟前
0
0
《告诉你真实的美国教育》的读后感3900字

《告诉你真实的美国教育》的读后感3900字: 文章的开篇分析了我们耳熟能详的关于美国教育的小故事,就是那个因为幼儿园的老师教了“0”这个字母,然后妈妈告老师剥夺了孩子的想象力,再然后幼...

原创小博客
24分钟前
0
0
Terraform配置文件(Terraform configuration)

Terraform配置文件 翻译自Terraform Configuration Terraform用文本文件来描述设备、设置变量。这些文件被称为Terraform配置文件,以.tf结尾。这一部分将讲述Terraform配置文件的加载与格式。...

buddie
39分钟前
2
0
exportfs命令, vsftp搭建ftp服务

exportfs命令 当修改/etc/exports文件后,更改的内容是不会立即生效的。如果重启nfs服务,会导致客户端重启期间的请求是挂起等待的,可以把客户端的挂载umount进行卸载后,再重启nfs服务,但...

野雪球
50分钟前
1
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部