【问题标题】:Django and formsetsDjango 和表单集
【发布时间】:2018-02-08 00:32:38
【问题描述】:

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

formset_factory函数创建formset类后,从BaseFormSet继承/获取属性,初始化新创建的类的一个对象,例如:

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

如果我检查dir(formset) form 和 forms 属性都可用,但如果我尝试打印forms 什么都没有打印,我想这与装饰器@cached_property有关(但何时调用?)

在formset对象的初始化中,没有与forms属性相关的操作。

所以,我想是在调用 {{formset}} 或 {{formset.as_p}} 等时调用的。

方法有:

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

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

(PS 我明白每个表单都在做什么),但不是表单中的表单,除了现在填充表单的事实

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

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

【问题讨论】:

    标签: django forms formset formsets


    【解决方案1】:

    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

    【讨论】:

      猜你喜欢
      • 2016-03-18
      • 1970-01-01
      • 2011-12-11
      • 1970-01-01
      • 1970-01-01
      • 2014-04-11
      • 1970-01-01
      • 2020-05-30
      • 2020-11-17
      相关资源
      最近更新 更多