Django和formsets

时间:2017-08-30 10:25:59

标签: django forms formset formsets

我试着理解Django表单集的内部是如何工作的。

在formset_factory函数创建formset类之后,从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)

为什么在自我中,我不明白,因为基于dir()的表单只是一个类,而self是formset对象。背后的逻辑是什么?

(PS我理解每种形式的做法),但不是形式的形式,除了现在填充的事实形式

之后,使用之前的management_form创建字段。

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

1 个答案:

答案 0 :(得分:2)

form in self导致调用特殊方法self.__iter__(),这是在python中实现可迭代类的方式。

  

object.__iter__(self)

     

当容器需要迭代器时,将调用此方法。此方法应返回一个新的迭代器对象,该对象可以迭代容器中的所有对象。对于映射,它应该迭代容器的键。

对于django的formset,这是相关的代码。

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