【问题标题】:How to show hidden autofield in django formset如何在 django formset 中显示隐藏的自动字段
【发布时间】:2010-10-28 02:59:48
【问题描述】:

默认情况下,使用表单集显示的 Django 自动字段是隐藏的。展示它的最佳方式是什么?

目前,模型声明为,

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

当它使用 Django 表单集呈现时,

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

它在页面上显示为,

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

谢谢。


编辑

我这样创建表单集 -

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

二次编辑

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

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

目前,我可以从 BaseModelFormSet 类继承并使用自定义查询集,也可以使用 ModelForm 类将自定义字段添加到 form。有没有办法同时使用表单集?


第三次修改

我现在正在使用,

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()

但这还是不行

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

【问题讨论】:

    标签: python django formset


    【解决方案1】:

    自动字段被隐藏的原因是 BaseModelFormSet 和 BaseInlineFormSet 都覆盖了 add_field 中的该字段。修复它的方法是创建自己的表单集并覆盖 add_field 而不调用 super。此外,您不必显式定义主键。

    您必须将表单集传递给 modelformset_factory:

        LocFormSet = modelformset_factory(MyModel, 
               formset=VisiblePrimaryKeyFormSet)
    

    这是在表单集类中:

    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
    

    【讨论】:

      【解决方案2】:

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

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

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

      • 与 {{form.locid.data}} 相同 - 正如上面提到的票证中所解释的那样。

      【讨论】:

        【解决方案3】:

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

        解决方案很简单——只需将自定义表单类传入modelformset_factory即可:

        LocFormSet = modelformset_factory(MyModel, form=MyModelForm) 
        

        编辑以响应更新 3:

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

        其次,将查询集放在 form 中根本不会做任何事情 - 表单不知道查询集。您应该回到之前所做的事情,在实例化表单集时将其作为参数传递。 (或者,您可以定义一个自定义 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')))
        

        【讨论】:

        • 感谢表单 = .. 上的信息。我不确定我是如何在文档中错过的!我仍然坚持我原来的问题 - 编辑不。问题中的 3 说明了当前代码。关于如何实现这一目标的任何想法?
        • 正如丹尼尔所说,您仍然需要将 locid 声明移到 init 方法之外。
        • 谢谢 - 查询集现在可以工作,但我仍然无法看到 locid!像上面一样完全地声明它 - locid 是类的一部分而不是 init - 我也有 self.fields 在那里 - 不要以 locid 结束.
        【解决方案4】:

        尝试更改默认字段类型:

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

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

        【讨论】:

        • 感谢您的回复。不幸的是,这似乎并没有改变页面上显示的内容..
        • 你重启服务器了吗?根据您的环境设置方式,您可能必须这样做。我刚刚测试了上述内容(使用我自己的模型,但同样的东西......)并且效果很好。
        • 嗯,我的更改通常会在没有重新启动的情况下显示(例如,添加新字段等) - 我有一个 apache/mod_python 设置,每个请求都会刷新..
        • 也许我们可以通过不同的方式创建表单集?我使用类似 LocFormSet = modelformset_factory(MyModel) pformset = LocFormSet(request.POST, request.FILES, queryset=MyModel.objects.order_by('name'))
        • 我不知道该告诉你什么,“它可以在我的机器上运行”:P 到底发生了什么?它只是一直显示一个隐藏的字段?
        猜你喜欢
        • 2013-02-14
        • 1970-01-01
        • 2015-12-29
        • 1970-01-01
        • 1970-01-01
        • 2016-07-17
        • 2013-09-11
        • 1970-01-01
        • 2010-11-18
        相关资源
        最近更新 更多