使用Django,我们可以以声明式的方式来定义一个Form,如下:

1
2
3
4
5
# -*- 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']

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

1
2
3
4
5
6
7
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)

这样就把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生成了一个新的类。

Django的Form机制小问题的更多相关文章

  1. 转载:Django之form表单

    转载: 一.使用form类创建一个表单 先定义好一个RegForm类: forms.py from django import forms # 导入forms类 class NameForm(form ...

  2. Django---form表单提交数据到数据库(普通方法+Django的form类)

    目标: ①.初始form的简单应用 ②.使用Django的form组件完成新增一个帖子 方法一:普通方法 1.前端表单代码 <div> <form class="navba ...

  3. Django之Form组件(一)

    Django之Form组件(一) Django的Form主要具有一下几大功能: 生成HTML标签 验证用户数据(显示错误信息) HTML Form提交保留上次提交数据 初始化页面显示内容 基本操作:字 ...

  4. python框架之Django(10)-Form组件

    介绍 我们之前在HTML页面中利用form表单向后端提交数据时,都会写一些获取用户输入的标签并且用form标签把它们包起来.与此同时我们在好多场景下都需要对用户的输入做校验,比如校验用户是否输入,输入 ...

  5. Django之Form、ModelForm 组件

    Django之Form.ModelForm 组件 一.Form组件: django框架提供了一个form类,来处理web开发中的表单相关事项.众所周知,form最常做的是对用户输入的内容进行验证,为此 ...

  6. Django 09 博客小案例

    Django 09 博客小案例 urls.py from django.urls import path from . import views urlpatterns = [ path('index ...

  7. Django 之 Form 组件

    常用功能 From 组件主要有以下几大功能: 生成 HTML 标签 验证用户数据(显示错误信息) HTML Form 提交保留上次提交数据 初始化页面显示内容 小试牛刀 下面我们通过 Form 组件来 ...

  8. Django之Form、跨站请求以及cookie、session

    Form表单 常规html页面的form表单验证 常规页面中,如果想实现对表单中用户输入信息的数据验证,需要配合Ajax来实现. 使用前我们先来熟悉下函数参数:request,其中包含的意义: req ...

  9. Django之Form组件

    Django之Form组件 本节内容 基本使用 form中字段和插件 自定义验证规则 动态加载数据到form中 1. 基本使用 django中的Form组件有以下几个功能: 生成HTML标签 验证用户 ...

随机推荐

  1. win7下设置挂载Linux服务器nfs共享的数据 -- 转

    最近学习NFS文件系统的使用,Ubuntu上配置好了,想和Win7共享数据,所以网上搜到了这篇文章.借花献佛,跟大家共享一下: http://www.2cto.com/os/201207/139132 ...

  2. window下卸载MySQL

    更多内容推荐微信公众号,欢迎关注: 网上找来的,留在这做个备份. 1.控制面板里的增加删除程序内进行删除 2.删除MySQL文件夹下的my.ini文件,如果备份好,可以直接将文件夹全部删除 3.开始- ...

  3. 假·最大子段和 (sdutoj 4359 首尾相连)(思维)

    题目链接:http://acm.sdut.edu.cn/onlinejudge2/index.php/Home/Contest/contestproblem/cid/2736/pid/4359 具体思 ...

  4. 用Nginx分流绕开Github反爬机制

    用Nginx分流绕开Github反爬机制 0x00 前言 如果哪天有hacker进入到了公司内网为所欲为,你一定激动地以为这是一次蓄谋已久的APT,事实上,还有可能只是某位粗线条的员工把VPN信息泄露 ...

  5. MVC Ajax Form & Ajax Valida(笔记)

    1.引入必要的文件 <script src=.min.js")" type="text/javascript"></script> &l ...

  6. 一种获取xml文件某个节点内容的shell方法

    配置文件 config.xml <xml> <server> <name>srv-01</name> </server> <serve ...

  7. tensorflow中的boolean_mask

    将mask中所有为true的抽取出来,放到一起,这里从n维降到1维度 tensor = [[1, 2], [3, 4], [5, 6]] import numpy as np mask=np.arra ...

  8. COLLATE CHINESE_PRC_CI_AS_WS 的含义

    排序规则:COLLATE CHINESE_PRC_CI_AS_WS 的含义 在创建数据表时,常会用到这个. 含义当中,CHINESE_prc_ 是代表中国大陆.如果是台湾,则如:Chinese_TAI ...

  9. 适合新手的web开发环境

    学习web开发,环境搭建是必不可少的一个环节.你可以使用wamp一键安装包,或者使用sae.bae.gae这种PaaS平台来部署,或者安装*nix系统在本地部署. 对于一个希望体验LAMP式建站的新手 ...

  10. Jquery Datatable添加复选框,实现批量操作。

    最近一段时间,一直在写前端的东西,自己也不擅长,最近也有所长进,把工作中用到的一些前端知识整理一下,下次用到就不用再找了.这次主要是在datatable中添加复选框,然后实现批量操作的功能.因为是公司 ...