Configure / Remove Django Selection Option

I am using Django 1.0.2. I wrote ModelForm supported by the model. This model has a ForeignKey, where blank = False. When Django generates HTML for this form, it creates a select box with one parameter for each row in the table referenced by ForeignKey. It also creates an option at the top of the list that does not matter and is displayed as a series of dashes:

<option value="">---------</option> 

What I would like to know:

  • What is the cleanest way to remove this automatically generated parameter from the selection window?
  • What is the cleanest way to configure it so that it displays as:

     <option value="">Select Item</option> 

Looking for a solution, I came across Django ticket 4653 , which gave me the impression that others had the same question and that the default behavior Perhaps Django was changed. This ticket is older than a year, so I was hoping there might be a cleaner way to accomplish these things.

Thanks for any help,

Jeff

Edit: I configured the ForeignKey field as such:

 verb = models.ForeignKey(Verb, blank=False, default=get_default_verb) 

This sets the default value so that it is no longer the empty / dashes parameter, but unfortunately this does not seem to solve my questions. That is, the empty / dashes parameter is still displayed in the list.

+66
python django django-models django-forms
Apr 11 '09 at 0:43
source share
12 answers

Did not test this, but based on reading Django code here and here I believe that it should work:

 class ThingForm(models.ModelForm): class Meta: model = Thing def __init__(self, *args, **kwargs): super(ThingForm, self).__init__(*args, **kwargs) self.fields['verb'].empty_label = None 

EDIT : documented , although you do not have to know ModelChoiceField if you are working with auto-generated ModelForm.

EDIT . As jlpp notes in his answer, this is not complete - you need to reassign the selection to widgets after changing the empty_label attribute. Since this is a bit hacked, another option that might be easier to understand is simply overriding the entire ModelChoiceField:

 class ThingForm(models.ModelForm): verb = ModelChoiceField(Verb.objects.all(), empty_label=None) class Meta: model = Thing 
+78
Apr 11 '09 at 12:40
source share

from documents

An empty selection will not be included if the model field has an empty value = False and an explicit default value (the default value will initially be selected instead).

so set the default and you're ok

+31
Apr 11 '09 at 0:58
source share

With Karl's answer as a guide, and after rooting around the Django source for hours, I think this is a complete solution:

  • To remove an empty option (Carl example):

     class ThingForm(models.ModelForm): class Meta: model = Thing def __init__(self, *args, **kwargs): super(ThingForm, self).__init__(*args, **kwargs) self.fields['verb'].empty_label = None # following line needed to refresh widget copy of choice list self.fields['verb'].widget.choices = self.fields['verb'].choices 
  • To set up an empty label, essentially the same:

     class ThingForm(models.ModelForm): class Meta: model = Thing def __init__(self, *args, **kwargs): super(ThingForm, self).__init__(*args, **kwargs) self.fields['verb'].empty_label = "Select a Verb" # following line needed to refresh widget copy of choice list self.fields['verb'].widget.choices = self.fields['verb'].choices 

I think this approach applies to all scenarios where ModelChoiceFields are displayed as HTML, but I'm not sure. I found that when these fields are initialized, their selection is passed to the Select widget (see Django.forms.fields.ChoiceField._set_choices). Setting an empty_class after initialization does not update the widget selection list. I am not familiar enough with Django to find out if this should be considered a mistake.

+20
Apr 12 '09 at 5:13
source share

You can use this in your model:

 class MyModel(models.Model): name = CharField('fieldname', max_length=10, default=None) 

default = None - answer: D

NOTE. I tried this on Django 1.7

+17
Jul 21 '14 at 15:22
source share

As for django 1.4, all you need to do is set "default" and "blank = False" in the selection box

 class MyModel(models.Model): CHOICES = ( (0, 'A'), (1, 'B'), ) choice_field = models.IntegerField(choices=CHOICES, blank=False, default=0) 
+8
Jul 30 '12 at 12:50
source share

See here for a full discussion and methods of solving this problem.

+5
Sep 01 '09 at 15:29
source share

you can do it in admin:

 formfield_overrides = { models.ForeignKey: {'empty_label': None}, } 
+5
Apr 27 '13 at 10:52
source share

self.fields['xxx'].empty_value = None does not work If you specify a TypedChoiceField field type that does not have the empty_label property.

We need to make the first choice:

1. If you want to create automatic detection BaseForm TypedChoiceField

 class BaseForm(forms.ModelForm): def __init__(self, *args, **kwargs): super(BaseForm, self).__init__(*args, **kwargs) for field_name in self.fields: field = self.fields.get(field_name) if field and isinstance(field , forms.TypedChoiceField): field.choices = field.choices[1:] # code to process other Field # .... class AddClientForm(BaseForm): pass 

2. only a few forms, you can use:

 class AddClientForm(forms.ModelForm): def __init__(self, *args, **kwargs): super(AddClientForm, self).__init__(*args, **kwargs) self.fields['xxx'].choices = self.fields['xxx'].choices[1:] 
+3
May 24 '15 at
source share

I was messing with this today and just came up with a pust hack solution:

 # Cowardly handle ModelChoiceField empty label # we all hate that '-----' thing class ModelChoiceField_init_hack(object): @property def empty_label(self): return self._empty_label @empty_label.setter def empty_label(self, value): self._empty_label = value if value and value.startswith('-'): self._empty_label = 'Select an option' ModelChoiceField.__bases__ += (ModelChoiceField_init_hack,) 

Now you can set the default ModelChoiceField an empty label for whatever you want. ModelChoiceField

PS: There is no need for downvotes, no harmful monkey patches are always convenient.

+2
Jan 12 '14 at 6:13
source share

For the latest version of django, the first answer should be like this:

 class ThingForm(models.ModelForm): class Meta: model = Thing def __init__(self, *args, **kwargs): self.base_fields['cargo'].empty_label = None super(ThingForm, self).__init__(*args, **kwargs)` 
+2
Mar 27 '15 at 14:33
source share

I find a SOLUTION !!

But not for ForeignKey :-)

Maybe I can help you. I looked in the Django source code and found that in django.forms.extras.widgets.SelecteDateWidget () is a property called none_value, which is equal to (0, '-----'), so I did this in my code

 class StudentForm(ModelForm): class Meta: this_year = int(datetime.datetime.today().strftime('%Y')) birth_years = [] years = [] for year in range(this_year - 2, this_year + 3 ): years.append(year) for year in range(this_year - 60, this_year+2): birth_years.append(year) model = Student exclude = ['user', 'fullname'] date_widget = SelectDateWidget(years=years) date_widget.__setattr__('none_value', (0, 'THERE WAS THAT "-----" NO THERES THIS:-)')) widgets = { 'beginning': date_widget, 'birth': SelectDateWidget(years=birth_years), } 
+1
Feb 14 '14 at 16:52
source share

In the ForeignKey field ForeignKey setting the default value to '' on the model will delete the empty parameter.

 verb = models.ForeignKey(Verb, on_delete=models.CASCADE, default='') 

For other fields, such as CharField , you can set default to None , but this does not work for ForeignKey fields in Django 1.11.

0
Sep 21 '17 at 14:55
source share



All Articles