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

时间:2012-10-20 00:04:27

标签: django django-forms

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

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

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

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

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

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

然而,这对我不起作用。当我在表单的 init 中包含该行时,“--------”仍然显示为选择框中的初始选项。我正在粘贴相关的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(),
    }

7 个答案:

答案 0 :(得分:9)

dokkaebi,这将无法正常工作。您将收到以下选择代码:

<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:] 

答案 1 :(得分:6)

实际上,现在(从 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'

如果字段应为readonly

,该怎么办?

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

如果在readonly_fields类中的PayrollCredentialAdmin属性中指定了被覆盖的表单字段,则KeyError会导致PayrollCredentialForm异常(因为readonly字段赢了& #39; t包含在表格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 :(得分:5)

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

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

答案 3 :(得分:1)

只有ModelChoiceField(为ForeignKey字段生成)支持empty_label参数,在这种情况下,由于这些字段通常由django.forms.models.ModelFormMetaclass生成,因此很难获得致电django.forms.models.modelform_factory

ModelFormMetaclass使用empty_label参数向列表中添加其他选项,其中empty_label为显示,''为其值。

执行所需操作的最简单方法就是在选择列表中添加一个空选:

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

        etc.....
                    )

答案 4 :(得分:1)

在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' 

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

答案 5 :(得分:0)

为我工作的另一种简单方法是:

country = forms.ModelChoiceField(queryset=Country.objects.filter(), empty_label='--Select--')

但是,我的Django版本是2.2.7

答案 6 :(得分:0)

改编自 Javed 答案。由于我的表单中有大量字段,我只想用占位符替换 html 中的所有标签,因此对于选择标签,我使用它们的字段标签。

class PacienteForm(forms.ModelForm):

    class Meta:
        model=Paciente
        fields=('__all__')

    def __init__(self, *args, **kwargs):
        super(PacienteForm, self).__init__(*args, **kwargs)

        for f in self.fields:
            if hasattr(self.fields[f], 'choices'):
                choices=self.fields[f].choices
                if type(choices) == list:
                    choices[0]=('',self.fields[f].label)
                    self.fields[f].choices=choices