Opened 6 months ago
Closed 6 months ago
#35569 closed Cleanup/optimization (fixed)
Misleading ValidationError wording from `limit_choices_to` violation
Reported by: | Jacob Walls | Owned by: | Jacob Walls |
---|---|---|---|
Component: | Database layer (models, ORM) | Version: | 4.2 |
Severity: | Normal | Keywords: | |
Cc: | Triage Stage: | Ready for checkin | |
Has patch: | yes | Needs documentation: | no |
Needs tests: | no | Patch needs improvement: | no |
Easy pickings: | no | UI/UX: | no |
Description
The ValidationError raised when a choice violating ForeignKey.limit_choices_to
is made refers to an instance "not existing", when in reality, the instance may exist but is simply not an allowed choice.
With the example field:
In [5]: Person(staff_member_id=2).full_clean() --------------------------------------------------------------------------- ValidationError Traceback (most recent call last) Cell In[5], line 1 ----> 1 Person(staff_member_id=2).full_clean() File ~/release/lib/python3.12/site-packages/django/db/models/base.py:1502, in Model.full_clean(self, exclude, validate_unique, validate_constraints) 1499 errors = e.update_error_dict(errors) 1501 if errors: -> 1502 raise ValidationError(errors) ValidationError: {'staff_member': ['user instance with id 2 does not exist.']} In [6]: User.objects.get(id=2) Out[6]: <User: anonymous>
We could use wording like "not a valid choice" and reuse that wording for nonexistent instances as well if there is a disclosure concern about introducing a distinction between the two cases.
Change History (5)
comment:1 by , 6 months ago
Summary: | Misleading ValidationError from `limit_choices_to` violation → Misleading ValidationError wording from `limit_choices_to` violation |
---|
comment:2 by , 6 months ago
Triage Stage: | Unreviewed → Accepted |
---|
comment:4 by , 6 months ago
Triage Stage: | Accepted → Ready for checkin |
---|
Note:
See TracTickets
for help on using tickets.
Changing the logic to disambiguate between "not exists" and "not matching" would require a non-negligible amount of work (we'd have to annotate the
limits_choice_to
criteria and check its value instead of simply doingqueryset = queryset.complex_filter(...)
) and introduces undesirable existence disclosure as you brought up.Switching the validation error message to "not a valid choice" makes sense though as it prevents disclosure, is not an invasive patch, and quite frankly is a better user error message.