2017-08-30 71 views
1

我試圖理解Django表單集的內部是如何工作的。Django和表單集

一個formset類後,通過formset_factory函數創建,繼承/從BaseFormSet,新創建的類的一個對象被初始化,例如獲得屬性:

ArticleFormSet = formset_factory(ArticleFormA, extra=2) 
formset = ArticleFormSet() 

如果我檢查與dir(formset)形式和形成屬性是可用的,但如果我嘗試打印forms沒有打印任何內容,我想這是關係到裝飾@cached_property(但當叫什麼名字?)

在該formset對象的初始化沒有涉及到forms屬性操作。

所以,我想調用時{{formset}}或{{formset.as_p}}等被調用。

的方法有:

forms = ' '.join(form.as_p() for form in self) 

爲什麼自我,我不明白,因爲基於目錄()形式就是一個類,自我是該formset對象。背後的邏輯是什麼?

(PS我明白了什麼是做打算每一種形式),但形式不形成,除了事實的形式現在被填充

而在此之後,使用management_form之前創建的領域。

return mark_safe('\n'.join([six.text_type(self.management_form), forms])) 

回答

2

form in self導致的特殊方法self.__iter__(),這是類如何迭代在Python實現通話。

object.__iter__(self)

當需要一種用於容器的迭代該方法被調用。這個方法應該返回一個新的迭代器對象,它可以迭代容器中的所有對象。對於映射,它應該迭代容器的鍵。

對於django的表單集,這是相關的代碼。

class BaseFormSet(object): 
    """ 
    A collection of instances of the same Form class. 
    """ 

    def __iter__(self): 
     """Yields the forms in the order they should be rendered""" 
     return iter(self.forms) 

    @cached_property 
    def forms(self): 
     """ 
     Instantiate forms at first property access. 
     """ 
     # DoS protection is included in total_form_count() 
     forms = [self._construct_form(i, **self.get_form_kwargs(i)) 
       for i in range(self.total_form_count())] 
     return forms 

link to full source