【问题标题】:How do I set initial values for extra fields on a Django Model Formset如何为 Django Model Formset 上的额外字段设置初始值
【发布时间】:2016-03-13 17:43:36
【问题描述】:

鉴于以下模型:

class ParentModel(models.Model):
    name = models.CharField(max_length=255)

class ChildModel(models.Model):
    name = models.CharField(max_length=255)
    weight = models.FloatField()
    parent = models.ForeignKey("ParentModel")

下面的 ModelForm 为 ChildModel 提供了一些额外的字段:

class ChildBalancingForm(forms.ModelForm):
    min_weight = forms.FloatField(min_value=0.0, max_value=1.0, required=True, label="Min Weight")
    max_weight = forms.FloatField(min_value=0.0, max_value=1.0, required=True, label="Max Weight")
    class Meta:
        model = ChildModel
        fields = []

我有一个有很多孩子的父模型。我需要使用一些数学来平衡孩子的体重(每个孩子的最小和最大体重都有一些界限)。因此,我正在尝试创建一个表单集,允许用户输入每个孩子的最小和最大重量以提交重新平衡。我想以所述形式指定默认的最小重量和默认的最大重量。因此,我认为以下几点:

# code to load up the parent whose children are being rebalanced..
# code to set a value for default_min_weight and default_max_weight
# code to get the number of children of said parent, num_children

initial_data = [{"min_weight": default_min_weight, "max_weight": default_max_weight},] * num_children
BalancingFormSet = modelformset_factory(ChildModel, form=ChildBalancingForm, extra=0, can_delete=False, min_num=num_children, max_num=num_children)
formset = BalancingFormSet(queryset=parent.childmodel_set.all(), initial=initial_data)

但是,当我输出表单时,我为 min_weight 和 max_weight 指定的默认值不显示(字段为空)。在我的表单集中为这些额外字段指定初始值的正确方法是什么?

【问题讨论】:

    标签: python django django-forms default formset


    【解决方案1】:

    这里的问题是ModelFormSets 重新定义了initial 参数以应用于额外的表单。然而,来源潜水表明我们可以用不同的名称重新添加它:

    # code to load up the parent whose children are being rebalanced..
    # code to set a value for default_min_weight and default_max_weight
    # code to get the number of children of said parent, num_children
    
    initial_data = [{"min_weight": default_min_weight, "max_weight": default_max_weight},] * num_children
    
    BalancingFormSetBase = modelformset_factory(ChildModel, form=ChildBalancingForm, extra=0, can_delete=False, min_num=num_children, max_num=num_children)
    
    class BalancingFormSet(BalancingFormSetBase):
        def __init__(self, *args, **kwargs):
            initial_forms_initial = kwargs.pop("initial_forms_initial", None)
            super(BalancingFormSet, self).__init__(*args, **kwargs)
            if not initial_forms_initial is None:
                self.initial = initial_forms_initial
    
    formset = BalancingFormSet(queryset=parent.childmodel_set.all(), initial_forms_initial=initial_data)
    

    我(草率地)在 Django 1.8 上测试了等效代码,但它并没有干扰实例属性 - 不过,如果您将 extra 设置为不是 0 的值,我没有检查会发生什么。

    从 1.9 开始,覆盖新的 get_form_kwargs 方法可能会更加健壮,因为它不假设我们可以覆盖 initial 属性而不会产生不必要的后果。

    当然,如果您不止一次使用此模式,则将这个 __init__ 定义放入基类或 mixin 可能是有意义的 - 但是,为了清晰和简单,我不在这里这样做。

    【讨论】:

      猜你喜欢
      • 2018-08-21
      • 2015-12-29
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-03-17
      • 2019-03-20
      • 2018-03-22
      • 2017-05-04
      相关资源
      最近更新 更多