Reputation: 5865
I created a model with a foreign key in it:
class Book(models.Model):
library = models.ForeignKey(Library, null=False, blank=False)
...
and then I created a form with a ModelForm to display to the users:
class BookSubmitForm(ModelForm):
class Meta:
model = Book
and when I display the page with the form I get the Library choices but also the blank (--------) choice that comes by default.
I thought by having null=False and blank=False in the model that would get rid of that blank choice in the ModelForm but no. What can I do to only have actual choices in the list and not that one?
Upvotes: 36
Views: 25082
Reputation: 1
The accepted solution works for choice fields which handle relationships, but it won't work for model fields that have the choices field set.
For anyone stumbling upon this question while trying to hide the empty choice field when choices is set, I got it working by providing my own custom CSS to my model form.
I don't know that hiding the empty choice field makes a lot of sense when using the default Select widget, but it does for the RadioSelect widget.
Make sure to configure your static files setting and then run python manage.py collectstatic
/* STATICFILES_DIRS/css/my_customizations.css */
#id_field_name :has(input[value='']) {
visibility: hidden;
padding: 0;
margin: 0;
height: 0;
}
class MyForm(forms.ModelForm):
class Meta:
model = MyModel
fields = "__all__"
widgets = {"field_name": forms.RadioSelect()}
# if you're using Django 3.x, you need set the class for inline
# widgets = {"field_name": forms.RadioSelect(attrs={"class": "inline li"})}
class Media:
css = {"all": ("css/my_customizations.css",)}
This let me have the option be null initially in the database, but ensure that writers select one of the two fields, and not change it from a valid value to the unset one.
Though, as of January 2023, :has
is not yet supported by Firefox, but will hopefully be supported sometime this year.
Upvotes: 0
Reputation: 82
Simply go to your list of choices (assuming you've made this a CharField) and provide the following code for None
:
Also, remember that this is an example, not pertaining to the code in question. It is simply meant to help anyone struggling with a default option.
GENDER_CHOICES = (
(None, 'Sex:'),
('M', 'Male'),
('F', 'Female'),
('G', 'Gay'),
('L', 'Lesbian'),
('B', 'Bi'),
('O', 'Other')
)
Choose_gender = models.CharField(max_length=1, choices=GENDER_CHOICES, blank=True)
By specifying None
, you are telling the choice field to default to a certain string. If you want to default to nothing, simply put ''
empty brackets.
Upvotes: 0
Reputation: 12488
If you specify blank=False
and default=<VALUE>
on the model field definition then Django will not render the blank choice by default; do note that the default value can be an invalid choice and set to ''
or any invalid choice
for example.
class Book(models.Model):
library = models.ForeignKey(Library, null=False, blank=False, default='')
...
Upvotes: 13
Reputation: 1399
See ModelChoiceField. You have to set empty_label to None. So your code will be something like:
class BookSubmitForm(ModelForm):
library = ModelChoiceField(queryset=Library.objects, empty_label=None)
class Meta:
model = Book
EDIT:changed the field name to lower case
Upvotes: 51
Reputation: 13808
self.fields['xxx'].empty_label = None
would not work If you field type is TypedChoiceField
which do not have empty_label
property.
What should we do is to remove first choice:
class BookSubmitForm(forms.ModelForm):
def __init__(self, *args, **kwargs):
super(BookSubmitForm, 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:]
Upvotes: 15
Reputation: 700
If you use ModelForm then you don't have to specify queryset, required, label, etc. But for the upvoted answer you have to do it again.
Actually you can do this to avoid re-specifying everything
class BookSubmitForm(ModelForm):
def __init__(self, *args, **kwargs):
super(BookSubmitForm, self).__init__(*args, **kwargs)
self.fields['library'].empty_label = None
class Meta:
model = Book
Upvotes: 12