10👍
The problem is that you are trying to specify something that is not available for the type of Select field.
The empty_label option is for forms.ModelChoiceField, which happens to use a Select widget, but is not the same kind of field as your CharField that you are providing options for.
https://docs.djangoproject.com/en/dev/ref/forms/fields/#modelchoicefield
You can see this also in a previous question here: https://stackoverflow.com/a/740011/1406860
You could try and override the html of the modelform to add the first option as “please choose value”. Alternatively, you could use a template filter to do the same thing. Lastly, you could and (“”, “please choose value”) to PAYROLL_CHOICES, and if you don’t want it to be submitted without a payrollProvider just set blank=False for the field in the model.
JD
16👍
dokkaebi, that won’t work properly. You’ll receive the following select code:
<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>
The only relatively convenient way that came to my mind is to do something like this in the form:
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:]
- [Django]-How to test Django's UpdateView?
- [Django]-__init__() got an unexpected keyword argument 'mimetype'
- [Django]-Django apps aren't loaded yet when using asgi
10👍
Actually, now (as of Django 1.8
and higher) override of an empty_label
works:
class PayrollCredentialForm(forms.ModelForm):
def __init__(self, *args, **kwargs):
super(PayrollCredentialForm, self).__init__(*args, **kwargs)
self.fields['payrollProvider'].empty_label = 'Please, choose value'
Also, if you working with Django Admin, there is an option to set empty value for a list view:
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
?
There is a catch if field modified in such way should be readonly
.
If overridden form field will be specified in readonly_fields
attribute inside PayrollCredentialAdmin
class, it would result in KeyError
exception in PayrollCredentialForm
(because readonly
field won’t be included in form’s self.fields
). To handle that, it’s required to override formfield_for_dbfield
instead of using 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
Might be useful.
Update for Django 1.11
:
Comments below brought assumption that such override is no longer valid for newer version of Django.
- [Django]-Django get objects not referenced by foreign key
- [Django]-Django JSONField inside ArrayField
- [Django]-Dynamic choices field in Django Models
3👍
In your forms.py file,
This would definitely work.. Try this…
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'
It worked for me.. just replace the field names with yours…
- [Django]-No URL to redirect to. Either provide a url or define a get_absolute_url method on the Model
- [Django]-Negating a boolean in Django template
- [Django]-Django TextField and CharField is stripping spaces and blank lines
1👍
Only ModelChoiceField
(generated for ForeignKey
fields) supports the empty_label
parameter, and in that case it’s tricky to get at as those fields are usually generated by django.forms.models.ModelFormMetaclass
within a call to django.forms.models.modelform_factory
.
ModelFormMetaclass
uses the empty_label
param to add another choice to the list, with empty_label
as the display and ''
as its value.
The simplest way to do what you want is just to add an empty choice to your choices list:
PAYROLL_CHOICES = (
('', 'please choose value'),
('C1', 'Choice1'),
('C2', 'Choice2'),
etc.....
)
- [Django]-How do I get the class of a object within a Django template?
- [Django]-Django-taggit – how do I display the tags related to each record
- [Django]-How to loop over form field choices and display associated model instance fields
1👍
Another simple way worked for me is:
country = forms.ModelChoiceField(queryset=Country.objects.filter(), empty_label='--Select--')
However, my Django version is 2.2.7
- [Django]-How do you configure Django to send mail through Postfix?
- [Django]-Suppress "?next=blah" behavior in django's login_required decorator
- [Django]-Get list item dynamically in django templates
1👍
Just add a tuple to your model.field.choices
with a value of None:
payrollProvider = models.CharField(max_length=2, choices=PAYROLL_CHOICES)
PAYROLL_CHOICES = (
(None, 'please choose'),
('C1', 'Choice1'),
('C2', 'Choice2')
etc.....
)
From the docs (v4.0):
Unless blank=False is set on the field along with a default then a label containing "———" will be rendered with the select box. To override this behavior, add a tuple to choices containing None; e.g. (None, ‘Your String For Display’). Alternatively, you can use an empty string instead of None where this makes sense – such as on a CharField.
- [Django]-Suddenly when running tests I get "TypeError: 'NoneType' object is not iterable
- [Django]-Is there a way to loop over two lists simultaneously in django?
- [Django]-Django: guidelines for speeding up template rendering performance
0👍
Adapted from Javed answer. Since I have tons of fields in my form I just want to replace all labels in the html by placeholders so for select tags I use their field label.
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
- [Django]-Itertools.groupby in a django template
- [Django]-What does 'many = True' do in Django Rest FrameWork?
- [Django]-How to merge consecutive database migrations in django 1.9+?
0👍
Add Empty String with "Please Select" to choices as shown below:
class DateForm(forms.ModelForm):
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
class Months(models.TextChoices):
EMPTY_LABEL = '', 'Please Select' # Here
JANUARY = 'JAN', 'January'
FEBRUARY = 'FEB', 'February'
MARCH = 'MAR', 'March'
self.fields['month'].choices = Months.choices
- [Django]-AccessDenied when calling the CreateMultipartUpload operation in Django using django-storages and boto3
- [Django]-How to assign items inside a Model object with Django?
- [Django]-Extend base.html problem