我正在使用Django 1.0.2 . 我写了一个由Model支持的ModelForm . 此模型有一个ForeignKey,其中blank = False . 当Django为此表单生成HTML时,它会创建一个选择框,其中包含ForeignKey引用的表中每一行的一个选项 . 它还在列表顶部创建一个没有值的选项,并显示为一系列破折号:
<option value="">---------</option>
我想知道的是:
-
从选择框中删除此自动生成选项的最简洁方法是什么?
-
最简洁的自定义方式是什么,它显示为:
<option value="">Select Item</option>
在搜索解决方案时,我遇到了Django ticket 4653,这给我的印象是其他人有同样的问题,并且Django的默认行为可能已被修改 . 这张票超过一年,所以我希望可能有更清洁的方法来完成这些事情 .
谢谢你的帮助,
杰夫
编辑:我已经配置了ForeignKey字段:
verb = models.ForeignKey(Verb, blank=False, default=get_default_verb)
这确实设置了默认值,因此它不再是空/短划线选项,但不幸的是它似乎无法解决我的任何问题 . 也就是说,空/破折号选项仍然出现在列表中 .
15 回答
对于最新版本的django,第一个答案应该是这样的
避风港't tested this, but based on reading Django' s代码here和here我相信它应该有效:
EDIT :这是documented,虽然你不会't necessarily know to look for ModelChoiceField if you'重新使用自动生成的ModelForm .
EDIT :正如jlpp在他的回答中指出的那样,这不是一个有点hacky,另一个可能更容易理解的选择就是覆盖整个ModelChoiceField:
来自文档
所以设置默认值就可以了
以Carl的回答为指导,在Django源码周围生根几个小时后,我认为这是完整的解决方案:
我认为这种方法适用于将ModelChoiceFields呈现为HTML的所有场景,但我并不积极 . 我发现当初始化这些字段时,它们的选择将传递给Select小部件(请参阅django.forms.fields.ChoiceField._set_choices) . 初始化后设置empty_label不会刷新Select小部件的选项列表 . 我对Django不太熟悉,知道这是否应该被视为一个bug .
您可以在模型上使用它:
default=None 就是答案:D
注意:我在Django 1.7上试过这个
至于django 1.4你需要的是在选择字段上设置“默认”值和“空白=假”
有关此问题的完整辩论和解决方法,请参阅here .
你可以在管理员中这样做:
self.fields['xxx'].empty_value = None
无效如果您的字段类型是TypedChoiceField
,它没有empty_label
属性 .我们应该做的是删除第一选择:
1 . 如果你想构建
BaseForm
自动检测TypedChoiceField
2.只有几种形式,你可以使用:
对于
ForeignKey
字段,在模型上将default
值设置为''
将删除空白选项 .对于像
CharField
这样的其他字段,您可以将default
设置为None
,但这不适用于Django 1.11中的ForeignKey
字段 .今天我正在搞乱这个问题,刚刚提出了一个懦夫黑客的漂亮解决方案:
现在,您可以将默认的
ModelChoiceField
空标签调整为您想要的任何内容 . :-)PS:不需要downvotes,无害的猴子补丁总是很方便 .
我找到解决方案!
但不适用于ForeignKey :-)
或许我可以帮你 . 我查看了Django源代码并发现在django.forms.extras.widgets.SelecteDateWidget()中是一个名为none_value的属性,它等于(0,'-----')所以我在我的代码中这样做了
这里有很多很棒的答案,但我对这些实现还不是很满意 . 我也有点沮丧的是,来自不同来源(外键,选择)的选择小部件会产生不同的行为 .
我有一个设计我正在使用选择字段 always 有一个空白选项,如果他们're required they will have a star next to them and the form will simply not validate if they'留空 . 也就是说,我只能正确地覆盖非
TypedChoiceField
字段的empty_label .这是结果应该是什么样子 . 第一个结果始终是字段的名称 - 在我的例子中,是
label
.这就是我最终做的事情 . 以下是我的表单的重写
__init__
方法:从Django 1.7开始,您可以通过在模型字段定义中的选项列表中添加值来自定义空白值的标签 . 从有关配置field choices的文档中:
我检查了不同版本的Django的文档,发现这是added in Django 1.7 .
当 choices are foreign keys 和 filter the choices based on some criteria 时,这会变得更加复杂 . 在这种情况下,如果您设置
empty_label
然后重新分配选项(您也可以在此处应用过滤),空标签将为空白:bbasically,
init
下的第一行可以应用于循环或内联循环的表单中的所有字段: