OtherField validators don't work with inline child objects
|Reported by:||slinkp@…||Owned by:||nobody|
|Cc:||Triage Stage:||Design decision needed|
|Has patch:||no||Needs documentation:||no|
|Needs tests:||no||Patch needs improvement:||no|
If you have a child model that references a parent model as a foreign key, and edit them inline in the django admin UI, you can't use any of the *OtherField validators such as IsLessThanOtherField.
The reason is that these validators expect the other_key parameter to be the exact name of the relevant form field; but with ForeignKey(edit_inline=...), the name is mangled.
I tried this workaround - but see the inline comments for why it's wrong:
class IsGreaterThanOtherField: """Django defines an IsLessThanOtherField validator, but it doesn't work on one-to-many children because the keys have some name-mangling going on. """ def __init__(self, other_field): self.other_field = other_field def __call__(self, field_data, all_data): # We have to iterate over them because we don't know the name of # our own field. for key, val in sorted(all_data.items()): if val == field_data: # Hope and pray there's no duplicate values. # If there are, this validator will only work for the first row. # The remaining rows will incorrectly compare against other_field from the first row. modelname, pkey, fieldname = key.split('.') myval = val break otherkey = '.'.join([modelname, pkey, self.other_field]) if myval <= all_data[otherkey]: raise validators.ValidationError( "Must be greater than the value of %s" % self.other_field)
I can't think of any way to work around this limitation, because the validator API doesn't provide any way that I see to know the actual name of the field we're validating.
Change History (3)
comment:1 Changed 6 years ago by slinkp@…
- Needs documentation unset
- Needs tests unset
- Patch needs improvement unset
comment:2 Changed 6 years ago by Karen Tracey <kmtracey@…>
- Triage Stage changed from Unreviewed to Design decision needed