深入学习Django源码基础14 - Django中forms简要分析

本篇采用分析源码学习的方式。

首先说一下forms模块文件夹结构

forms
|----extras
     |----__init__.py
     |----widgets.py
|----__init__.py
|----fields.py
|----forms.py
|----formsets.py
|----models.py
|----util.py
|----widgets.py

分析 widgets.py中有Media类

分析其中主要完成2件事情

1:js和css路径设置

2:js和css路径渲染

渲染部分
def render(self):
        return mark_safe('\n'.join(chain(*[getattr(self, 'render_' + name)() for name in MEDIA_TYPES])))

    def render_js(self):
        return [format_html('<script type="text/javascript" src="{0}"></script>', self.absolute_path(path)) for path in self._js]

    def render_css(self):
        # To keep rendering order consistent, we can't just iterate over items().
        # We need to sort the keys, and iterate over the sorted list.
        media = sorted(self._css.keys())
        return chain(*[
                [format_html('<link href="{0}" type="text/css" media="{1}" rel="stylesheet" />', self.absolute_path(path), medium)
                    for path in self._css[medium]]
                for medium in media])

接下来定义部件类

部件基类(包含,渲染,label提示,取值),封装常见的form控件类。主要是显示部分。


接下来看fields.py

fields类封装了对应的部件与程序员交互部分的方法。(验证,更多显示操控。初始化,本地化等操作)

并基于部件,做了1些深层的字段封装(邮件字段,邮箱字段,时间,日期,正则。)。

主要目的用于将orm的字段对应到前端。对应到部件。


接下来看forms.py

有了部件和field的封装以后。

1个form中有多个fields如何处理。显示。

 

接下来看formsets.py文件,进入更牛B的批量生产工厂

def formset_factory(form, formset=BaseFormSet, extra=1, can_order=False,
                    can_delete=False, max_num=None):
    if max_num is None:
        max_num = DEFAULT_MAX_NUM
    absolute_max = max(DEFAULT_MAX_NUM, max_num)
    attrs = {'form': form, 'extra': extra,
             'can_order': can_order, 'can_delete': can_delete,
             'max_num': max_num, 'absolute_max': absolute_max}
    return type(form.__name__ + str('FormSet'), (formset,), attrs)

新建1个formFormSet的类。基类是BaseFromSet。属性有 form,extra。。。

在初始化内部调用


def _construct_forms(self):
        self.forms = []
        for i in xrange(min(self.total_form_count(), self.absolute_max)):
            self.forms.append(self._construct_form(i))

根据数量构造form

下面是抽象出来的模拟理解过程的代码

def with_metaclass(meta, base=object):
    return meta("NewBase", (base,), {})

def get_declared_fields(base, attrs):
    print base, attrs

class DeclarativeFieldsMetaclass(type):
    def __new__(cls, name, bases, attrs):
        attrs['base_fields'] = get_declared_fields(bases, attrs)
        new_class = super(DeclarativeFieldsMetaclass, cls).__new__(cls, name, bases, attrs)
        return new_class

class BaseForm(object):
    def __init__(self):
        pass

class Form(with_metaclass(DeclarativeFieldsMetaclass, BaseForm)):
    pass

class BaseFormSet(object):
    def __init__(self):
        pass

def formset_factory(form, formset=BaseFormSet, extra = 1):
    attrs = {'form':form, 'extra':extra}
    return type(form.__name__ + str("FormSet"), (formset,), attrs)

class subForm(Form):
    def __init__(self):
        print 'subForm'

formsets = formset_factory(subForm)
print formsets
print formsets.__dict__

接下来看models.py文件

Helper functions for creating Form classes from Django models and database field objects.

 models.py中封装了类似formset的方法。与其他方法(下次看文档时候在具体分析)

关于其中的用法 

http://my.oschina.net/xorochi/blog/125802

http://i.appspot.com/blog/2009/jan/11/django-dynamic-modelform/

官方使用方法

https://docs.djangoproject.com/en/dev/topics/forms/modelforms/#modelforms-factory


util.py中定义没什么好说的


你可能感兴趣的:(深入学习Django源码基础14 - Django中forms简要分析)