默认情况下,隐藏使用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()
但这仍然没有
答案 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)
好的,上述方法都不适合我。我终于从模板方面解决了这个问题。
有一张票据(http://code.djangoproject.com/ticket/10427),它为表单的模板变量添加了“值”选项。例如,它允许,
{{form.locid.value}}
显示。这是一个补丁,可以使用“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