文档章节

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+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
Django Form表单基础

平时我们写表单要自己写样式,比如我们要写一个注册样式,有如下填写项: 实现代码如下: views.py文件 函数userlist中从userlist.html文件中提交(POST)过来的数据,再以request获取POST方式...

技术小胖子
2017/11/17
0
0

没有更多内容

加载失败,请刷新页面

加载更多

中国移动蔡谦:5G传输准备就绪

目前5G已成业界热议话题,在即将到来的万物互联时代,5G是非常关键的技术。且5G相比4G,业务场景多种多样,对5G承载网带来巨大挑战。5G传输,承载先行并不仅仅是一个口号。当前5G承载网的部署...

linux-tao
22分钟前
4
0
维护“修理权”,苹果使用专有软件工具来修复MacBook Pro和iMac Pro

根据上月发给苹果授权服务提供商的一份文件,苹果公司正在使用新的专有软件诊断工具来修复MacBook Pros和iMac Pros,如果不用专有软件工具来修复关键部件,将会导致“系统失效和修复不完整”...

linuxCool
52分钟前
2
0
cacti监控安装

cacti是用PHP实现的一个软件,它用snmp服务获取数据,然后用rrdtool存储和更新数据,并生成图表展示。比较适合用于交换机、路由器的网络监控,插件众多,可图示化显示网络状况。 cacti官方推...

hiwill
今天
4
0
shell特殊符号、cut、sort、uniq、wc、tee、tr、split命令

10月15日任务 8.10 shell特殊符号cut命令 8.11 sort_wc_uniq命令 8.12 tee_tr_split命令 8.13 shell特殊符号下 cut 命令 cut作用:截取字符串 用法如下:cat /etc/passwd |head -2 |cut -d ...

hhpuppy
今天
4
0
Springboot实现filter拦截token验证和跨域

背景 web验证授权合法的一般分为下面几种 1使用session作为验证合法用户访问的验证方式 使用自己实现的token 使用OCA标准 在使用API接口授权验证时,token是自定义的方式实现起来不需要引入其...

funnymin
今天
4
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部