Как изменить empty_label для поля выбора модели модели?

У меня есть поле в одной из моих моделей, например:

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

Когда я создаю модельную форму для этого поля, Django правильно генерирует поле выбора HTML, но включает пустое значение по умолчанию "---------".

Я хотел бы знать, как изменить это значение по умолчанию на какой-либо другой текст, например, "пожалуйста, выберите значение".

Я считаю, что мне нужно установить это в моей модельной форме init следующим образом, как описано в в этом ответе и несколько других:

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

Однако это не работает для меня. Когда я включаю эту строку в свою форму init, "--------" по-прежнему отображается как исходный выбор в поле выбора. Я вставляю соответствующие формы .py ниже, но, похоже, другим также не удалось получить доступ/изменить пустую_клавишу. По этой ссылке, вопросник описывает способ удаления значения по умолчанию 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(),
    }

Ответ 1

Проблема заключается в том, что вы пытаетесь указать что-то, недоступное для типа поля "Выбрать".

Опция empty_label предназначена для форм .ModelChoiceField, который используется для использования виджета Select, но не является тем же видом поля, что и ваш CharField, для которого вы предоставляете параметры.

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

Вы также можете увидеть это в предыдущем вопросе: fooobar.com/questions/83351/...

Вы можете попробовать и переопределить html modelform, чтобы добавить первый вариант как "пожалуйста, выберите значение". Кроме того, вы можете использовать фильтр шаблонов, чтобы сделать то же самое. Наконец, вы можете и ("", "пожалуйста, выберите значение" ) в PAYROLL_CHOICES, и если вы не хотите, чтобы он был отправлен без расчета, Provider просто установил blank = False для поля в модели.

JD

Ответ 2

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

Ответ 3

На самом деле, теперь (из 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 не будет включено в форму 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.

Ответ 4

Только 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.....
                    )

Ответ 5

В файле 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' 

Это сработало для меня.. просто замените имена полей вашими...