Как изменить 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'
Это сработало для меня.. просто замените имена полей вашими...