Django的Form机制详解

编辑:光环大数据 来源: 互联网 时间: 2017-10-18 10:41 阅读:

Django的Form机制详解

环境:Python 2.7.5 + Django 1.6

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

# -*- coding: utf-8 -*-from django import formsclass 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__方法:

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

 
 Python培训,就选光环大数据Python培训机构python学习地址:http://hadoop.aura.cn/python/

 


大数据培训、人工智能培训、Python培训、大数据培训机构、大数据培训班、数据分析培训、大数据可视化培训,就选光环大数据!光环大数据,聘请专业的大数据领域知名讲师,确保教学的整体质量与教学水准。讲师团及时掌握时代潮流技术,将前沿技能融入教学中,确保学生所学知识顺应时代所需。通过深入浅出、通俗易懂的教学方式,指导学生更快的掌握技能知识,成就上万个高薪就业学子。 更多问题咨询,欢迎点击------>>>>在线客服

你可能也喜欢这些

在线客服咨询

领取资料

X
立即免费领取

请准确填写您的信息

点击领取
#第三方统计代码(模版变量) '); })();
'); })();