深入學習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中定義沒什麼好說的


發佈了104 篇原創文章 · 獲贊 8 · 訪問量 61萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章