如何在django formset中显示隐藏的autofield

时间:2009-05-22 02:29:31

标签: python django formset

默认情况下,隐藏使用formset显示时的Django自动对话框。展示它的最佳方式是什么?

目前,该模型被声明为

class MyModel:
   locid = models.AutoField(primary_key=True)
   ...

使用Django formsets渲染时,

class MyModelForm(ModelForm):
  class Meta:
    model = MyModel
    fields = ('locid', 'name')

它显示在页面上,

<input id="id_form-0-locid" type="hidden" value="707" name="form-0-locid"/>

感谢。


修改

我创建了这样的formset -

LocFormSet = modelformset_factory(MyModel) 
pformset = LocFormSet(request.POST, request.FILES, queryset=MyModel.objects.order_by('name')) 

第二次修改

看起来我没有使用我在那里定义的自定义表单类,所以这个问题需要稍加修改..

如何从自定义表单(将显示隐藏字段)创建表单集,以及使用自定义查询集?

目前,我可以继承BaseModelFormSet类并使用自定义查询集,或者我可以使用ModelForm类将自定义字段添加到表单。有没有办法用formset做两件事?


第三次修改

我现在正在使用,

class MyModelForm(ModelForm):
  def __init__(self, *args, **kwargs):
    super(MyModelForm, self).__init__(*args, **kwargs)
    locid = forms.IntegerField(min_value = 1, required=True)
    self.fields['locid'].widget.attrs["type"] = 'visible'
    self.queryset = MyModel.objects.order_by('name')
  class Meta:
    model = MyModel
    fields = ('locid', 'name')

LocFormSet = modelformset_factory(MyModel, form = MyModelForm)
pformset = LocFormSet()

但这仍然没有

  • 显示locid
  • 使用指定的自定义查询。

4 个答案:

答案 0 :(得分:2)

尝试更改默认字段类型:

from django import forms
class MyModelForm(ModelForm):
  locid = forms.IntegerField(min_value=1, required=True)
  class Meta:
    model = MyModel
    fields = ('locid', 'name')

编辑:已经过测试并且有效......

答案 1 :(得分:1)

正如您所说,您没有使用已定义的自定义表单。这是因为你没有把它传递到任何地方,所以Django无法知道它。

解决方案很简单 - 只需将自定义表单类传递给modelformset_factory:

LocFormSet = modelformset_factory(MyModel, form=MyModelForm) 

编辑以响应更新3:

首先,您在错误的位置重新定义了locid - 它需要在类级别,而不是在__init__内。

其次,将查询集放在表单中根本不会做任何事情 - 表单不了解查询集。您应该回到之前所做的事情,在实例化formset时将其作为参数传递。 (或者,您可以定义自定义 formset ,但这看起来有点矫枉过正。)

class MyModelForm(ModelForm):
    locid = forms.IntegerField(min_value=1, required=True)

    def __init__(self, *args, **kwargs):
        super(MyModelForm, self).__init__(*args, **kwargs)
        self.fields['locid'].widget.attrs["type"] = 'visible'
    class Meta:
        model = MyModel
        fields = ('locid', 'name')

LocFormSet = modelformset_factory(MyModel, form = MyModelForm)
pformset = LocFormSet(request.POST, request.FILES,
                      queryset=MyModel.objects.order_by('name')))

答案 2 :(得分:0)

好的,上述方法都不适合我。我终于从模板方面解决了这个问题。

显示。这是一个补丁,可以使用“patch -p0 file.patch”安装在django的SVN版本中

  • 请记住,{{form.locid.value}}变量将与结合与不可见的表单一起使用 - 否则,表单集的提交和保存操作将崩溃。 / p>

  • 与{{form.locid.data}}相同 - 正如上面提到的故障单中所述。

答案 3 :(得分:0)

隐藏自动对话的原因是BaseModelFormSet和BaseInlineFormSet都覆盖了add_field中的该字段。修复它的方法是创建自己的formset并覆盖add_field而不调用super。您也不必明确定义主键。

你必须将formset传递给modelformset_factory:

    LocFormSet = modelformset_factory(MyModel, 
           formset=VisiblePrimaryKeyFormSet)

这是在formset类中:

from django.forms.models import BaseInlineFormSet, BaseModelFormSet, IntegerField
from django.forms.formsets import BaseFormSet

class VisiblePrimaryKeyFormset(BaseModelFormSet):
    def add_fields(self, form, index):
        self._pk_field = pk = self.model._meta.pk
        if form.is_bound:
            pk_value = form.instance.pk
        else:
            try:
                pk_value = self.get_queryset()[index].pk
            except IndexError:
                pk_value = None
        form.fields[self._pk_field.name] = IntegerField( initial=pk_value,
                 required=True) #or any other field you would like to display the pk in
        BaseFormSet.add_fields(self, form, index) # call baseformset which does not modify your primary key field