#34635 closed Uncategorized (wontfix)
ModelChoiceField with a to_attr that can have an EMPTY_VALUE
Reported by: | Willem Van Onsem | Owned by: | nobody |
---|---|---|---|
Component: | Forms | Version: | 4.2 |
Severity: | Normal | Keywords: | |
Cc: | Triage Stage: | Unreviewed | |
Has patch: | no | Needs documentation: | no |
Needs tests: | no | Patch needs improvement: | no |
Easy pickings: | no | UI/UX: | no |
Description
Recently a person asked this question on [StackOverflow](https://stackoverflow.com/questions/76409430/django-testing-a-simple-model-with-foreign-key-and-updateview/76409867). Imagine we have the following models:
from django.db import models class Location(models.Model): location_number = models.CharField(max_length=30, unique=True) name = models.CharField(max_length=128) class Project(models.Model): location = models.ForeignKey(Location, on_delete=models.CASCADE, to_field='location_number', db_column='location_number', related_name='projects', verbose_name='Standort')
Then it is possible to construct a Location
with an empty string for location_number
:
Location.objects.create(location_number='', name='location_name')
But now if we construct a ModelForm
, it will not accept this as valid option, indeed:
class ProjectForm(forms.ModelForm): class Meta: model = Project fields = ['location']
This will render a <select>
with the values of the to_field
as values, so:
<select name="location"> <option value="">location_name</option> </select>
now if the form is submitted, it will pass the empty string for location
, but the form field will reject it because the field is required, and it sees this as an empty value.
The problem is thus a bit of a mismatch between what a form does and the possible values of a model. Unfortunately I don't see an easy solution for this. Perhaps the checks framework can at least warn if a ForeignKey
refers to a CharField
or another field that can have an empty value.
Change History (4)
comment:1 by , 17 months ago
Component: | Uncategorized → Forms |
---|---|
Resolution: | → needsinfo |
Status: | new → closed |
comment:2 by , 17 months ago
Yes, but that seems counterintuitive, since it seems to suggest that you leave the *reference* blank, we here leave the location_id
blank, but the form definitely refers to a Location
. So it seems counterintuitive, and misleading.
comment:3 by , 17 months ago
imho this is exactly what blank is for :P https://docs.djangoproject.com/en/4.2/ref/models/fields/#blank
If True, the field is allowed to be blank … Note that this is different than null. null is purely database-related, whereas blank is validation-related. If a field has blank=True, form validation will allow entry of an empty value.
The key here is that ""
is an empty value. blank=True
is declaring that empty values are permissible.
since it seems to suggest that you leave the *reference* blank
Are you referring to null/None
? 🤔
So it seems counterintuitive, and misleading.
And so the NULL
debate rages on 😅
comment:4 by , 17 months ago
Resolution: | needsinfo → wontfix |
---|
Yes, ...
Great, so it works as documented. That's why we have blank
.
... but that seems counterintuitive
We had this debate so many times, we cannot change the long standing behavior for an edge case of blank primary keys. TBH, I don't find it misleading that you have to set blank=True
to allow for blank foreign keys.
You can start a discussion on DevelopersMailingList if you don't agree, however, I don't think there would be consensus to change the current behavior.
Is it not enough to set
blank=True
to aForeignKey
?