如何为modelForm选择字段更改empty_label?

我在我的一个模型中有一个字段,如下所示:

payrollProvider = models.CharField(max_length=2, choices=PAYROLL_CHOICES)
 PAYROLL_CHOICES = (
        ('C1', 'Choice1'),
        ('C2', 'Choice2')
        etc.....
                    )

当我为该字段创建模型表单时,Django正确生成HTML选择框,但包含默认空白值“---------” .

我想知道如何将此默认值更改为其他文本,例如“请选择值” .

我相信我应该可以通过以下内容在我的模型表单_2778165中设置它,如文档in this answer和其他几个:

self.fields['payrollProvider'].empty_label = "please choose value"

但是,这不是't working for me. When I include that line in my form',"--------"仍然显示为选择框中的初始选项 . 我正在粘贴下面的相关forms.py,但似乎其他人有also been unable to access / modify empty_label . 在这个链接中,提问者描述了一种删除默认empty_label值的方法(我能够通过他的方法成功完成),但我真正想做的是修改显示的empty_label .

有任何想法吗?

这是forms.py中表单的代码,其中empty_label代码在更改默认值“----------”时未成功:

class PayrollCredentialForm(forms.ModelForm):
    def __init__(self, *args, **kwargs):
        super(PayrollCredentialForm, self).__init__(*args, **kwargs)
        self.fields['payrollUsername'].widget.attrs.update({'class' : 'yp-signup'})
        self.fields['payrollPassword'].widget.attrs.update({'class' : 'yp-signup'})
        self.fields['payrollProvider'].widget.attrs.update({'class' : 'yp-signup'})
        self.fields['payrollUsername'].widget.attrs.update({'placeholder' : '  Payroll Username'})
        self.fields['payrollPassword'].widget.attrs.update({'placeholder' : '  Payroll Password'})
        self.fields['payrollProvider'].empty_label = "please choose value"


class Meta:
    model = Company
    fields = ('payrollProvider', 'payrollUsername', 'payrollPassword')
    widgets = {
        'payrollPassword': forms.PasswordInput(),
    }

回答(5)

2 years ago

问题是您正在尝试指定“选择”字段类型不可用的内容 .

empty_label选项适用于forms.ModelChoiceField,它恰好使用Select小部件,但与您为其提供选项的CharField不是同一类型的字段 .

https://docs.djangoproject.com/en/dev/ref/forms/fields/#modelchoicefield

你也可以在上一个问题中看到这个:https://stackoverflow.com/a/740011/1406860

您可以尝试覆盖模型窗体的html,将第一个选项添加为“请选择值” . 或者,您可以使用模板过滤器来执行相同的操作 . 最后,您可以和(“”,“请选择值”)到PAYROLL_CHOICES,如果您不希望在没有payrollProvider的情况下提交它,只需为模型中的字段设置blank = False .

JD

2 years ago

dokkaebi,赢得't work properly. You'将收到以下选择代码:

<select name="payrollProvider" id="id_payrollProvider">
<option value="" selected="selected">---------</option>
<option value="" selected="selected">please choose value</option>
<option value="C1">Choice1</option>
<option value="C2">Choice2</option>
</select>

我想到的唯一相对方便的方法是在表单中做这样的事情:

class PayrollCredentialForm(forms.ModelForm):
    class Meta:
        model = Company
    def __init__(self, *args, **kwargs):
        super(PayrollCredentialForm, self).__init__(*args, **kwargs)
        self.fields["payrollProvider"].choices = [("", "please choose value"),] + list(self.fields["payrollProvider"].choices)[1:]

2 years ago

实际上,现在(截至 Django 1.8 及更高版本)覆盖 empty_label 的工作原理:

class PayrollCredentialForm(forms.ModelForm):
    def __init__(self, *args, **kwargs):
        super(PayrollCredentialForm, self).__init__(*args, **kwargs)
        self.fields['payrollProvider'].empty_label = 'Please, choose value'

此外,如果您使用 Django Admin ,则可以选择为列表视图设置空值:

class PayrollCredentialAdmin(admin.ModelAdmin):
    list_display = ('payrollProvider_value', )

    def payrollProvider_value(self, instance):
        return instance.payrollProvider
    payrollProvider_value.empty_value_display = 'Empty value'

What if field should be readonly?

如果以这种方式修改的字段应为 readonly ,则有一个catch .

如果在 PayrollCredentialAdmin 类中的 readonly_fields 属性中指定了重写的表单字段,则会在 PayrollCredentialForm 中导致 KeyError 异常(因为 readonly 字段赢了't be included in form' s self.fields ) . 要处理它,需要覆盖 formfield_for_dbfield 而不是使用 readonly_fields

def formfield_for_dbfield(self, db_field, **kwargs):
    field = super(PayrollCredentialAdmin, self).formfield_for_dbfield(
        db_field, **kwargs
    )
    db_fieldname = canonical_fieldname(db_field)

    if db_fieldname == 'payrollProvider':
        field.widget = forms.Select(attrs={
            'readonly': True, 'disabled': 'disabled',
        })

    return field

可能有用 .


更新 Django 1.11

下面的评论假设这种覆盖对于较新版本的Django不再有效 .

2 years ago

只有 ModelChoiceField (为 ForeignKey 字段生成)支持 empty_label 参数,在这种情况下,由于这些字段通常由 django.forms.models.ModelFormMetaclassdjango.forms.models.modelform_factory 调用中生成,因此很难处理 .

ModelFormMetaclass 使用 empty_label param为列表添加另一个选项,其中 empty_label 为显示, '' 为其值 .

做你想做的最简单的方法就是在你的选择列表中添加一个空选:

PAYROLL_CHOICES = (
        ('', 'please choose value'),
        ('C1', 'Choice1'),
        ('C2', 'Choice2'),

        etc.....
                    )

2 years ago

在你的forms.py文件中,这肯定有用..试试这个......

class Meta:
        model = StaffDetails
        fields =['photo','email', 'first_name','school','department', 'middle_name','last_name','gender', 'is_active']
     def __init__(self, *args, **kwargs):
        super(StaffDetailsForm, self).__init__(*args, **kwargs)
        self.fields['Field_name'].empty_label = 'Please Select'

它对我有用..只需用你的字段替换字段名称......