【问题标题】:Why does my excluded field still appear in this Django form?为什么我的排除字段仍然出现在这个 Django 表单中?
【发布时间】:2011-12-29 16:03:59
【问题描述】:

我在表单的 Meta 类中使用 exclude 从表单中排除我想以编程方式填写的字段,但它仍然显示在表单中。

以下是部分代码摘录:

# Model
class Info(models.Model):
    completed_by = models.ForeignKey(User, related_name='+')

# Form
class InfoForm(forms.ModelForm):
    class Meta:
        model = Info
        exclude = ('created_by',)  #ETA: added comma to make this a tuple
        widgets = {
            'some_other_field': forms.HiddenInput(),
            'some_other_field2': forms.DateInput(attrs={'readonly': True}),
        }

# View
form = InfoForm(initial={'some_other_field': value}, 
                          prefix='info', instance=info)
return direct_to_template(request, 'myapp/info.html', locals())

# Template
<form class='uniForm' method='POST'>
{% csrf_token %}
<fieldset class='inlineLabels'>{{ form|as_uni_form }}</fieldset>
<input type='submit' name='action' value='Save' />
</form>

这看起来应该很简单,而且我知道我之前已经成功完成了。我已经删除/重新创建了我的数据库并清除了我的浏览器缓存,以确保这不是一个因素。我还尝试将其设为HiddenInput 字段,就像some_other_field(也是ForeignKey 字段)一样,但它仍然显示在表单上。

这里有什么我遗漏的吗? uni_form 是否以某种方式覆盖了设置?如果没有,关于我可能在调试中寻找什么以了解发生这种情况/原因的任何建议?

(使用 Django 版本 1.2.7)

【问题讨论】:

  • 如果你只渲染{{ form }}而不是使用uni_form,它还会出现吗?
  • 好主意...是的,当呈现为 {{ form }} 时,它仍然会出现。
  • hm.. 只是为了确保:您的模型有completed_by,但您排除了created_by。仅在示例中,对吗?
  • 啊……是的,就是这样。 :|太明显了,我猜。感谢您的帮助!

标签: django django-forms


【解决方案1】:

exclude 需要一个元组,所以你需要

# note the extra comma
exclude = ('created_by',)

django 遍历exclude,并且由于字符串是可迭代的(返回每个字符)这不会引发错误

【讨论】:

  • 你说得对,那应该是一个元组。谢谢。不过,修复后该字段仍会显示在表单中。
  • 元组+更正completed_by/created_by(如您在上面推荐的)做到了。再次感谢。
  • 好吧,伙计们,我运气不好。我排除了该字段并确保该字段后有逗号。该字段仍会被渲染。
【解决方案2】:

我知道这是旧的,但在这里发布作为参考。

我遇到了同样的问题,因为我在模型上重载了clean_fields(),但没有正确调用超类。

 class MyModel(models.Model):
    foo = models.BooleanField()    

    # Wrong!  Don't do this!
    def clean_fields(self, exclude=None):
        # Bah!  Forgetting to pass exclude defaults it to None!
        super(MyModel, self).clean_fields()
        if not self.foo:
            raise ValidationError('Ah fooey.')

    # Correct!  Do it this way!
    def clean_fields(self, exclude=None):
        # That's better!  Let's take a coffee break.  I'm tired.
        super(MyModel, self).clean_fields(exclude)
        if not self.foo:
            raise ValidationError('Ah fooey.')

【讨论】:

    【解决方案3】:

    对于较旧的 Django 版本,排除您明确声明的非模型字段存在问题,例如在父表单类中。即使对于非模型字段,在表单的 init 中添加以下内容也会处理它(请参阅https://code.djangoproject.com/ticket/8620)。

    def __init__(self, *args, **kwargs):
        super(MyForm, self).__init__(*args, **kwargs)
        [self.fields.pop(f) for f in self.fields.keys() if f in self.Meta.exclude]
    

    【讨论】:

    • 谢谢!这也适用于继承的 ModelForm,比如我的 wagtail 案例 UserForm。
    • 这对我也有用,尽管我需要将 self.fields.keys() 设为一个列表,以便能够在迭代时发生变异(在列表理解中)
    猜你喜欢
    • 2023-03-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-09-10
    • 1970-01-01
    • 2017-10-08
    相关资源
    最近更新 更多