Reputation: 2998
I have a Django model, something like:
class MyModel(models.Model):
no_validation = models.PositiveIntegerField(null=True, db_index=True)
yes_validation = models.CharField(max_length=254, validators=[my_validator])
I also have a pre-save hook that goes something like:
@receiver(pre_save, sender=MyModel)
def run_full_clean(sender, instance, **kwargs):
instance.clean_fields()
My issue is that this current approach cleans all fields. I want to only clean one specific field (the one called yes_validation). Is there an easy way to do that?
I'm only aware of the exclude
parameter, but the issue is my class has almost a hundred different fields and so it would be a bit dirty to exclude every single one.
Upvotes: 6
Views: 9127
Reputation: 365
I ran into this issue and ended up creating a mixin for selectively cleaning provided fields.
This can be achieved by calling full_clean
, letting a ValidationError be thrown and caught and then only re-raising it if the selected field is in the error_dict
attribute of the error:
class SelectiveCleanMixin:
def full_clean(self) -> None:
"""Dummy full_clean method for type hinting."""
...
def selective_clean(self, *fields: list[str]):
"""Selectively clean the provided list of fields."""
try:
self.full_clean()
except ValidationError as exc:
errors = {k: v for (k, v) in exc.error_dict.items() if k in fields}
if errors:
raise ValidationError(errors)
Upvotes: 0
Reputation: 25539
You could override clean
method instead of using clean_fields
method. Quoting from django docs:
Model.clean()
This method should be used to provide custom model validation, and to modify attributes on your model if desired. For instance, you could use it to automatically provide a value for a field, or to do validation that requires access to more than a single field.
I'm not sure about this way of doing the validation because I don't really support validating data on models. To me models are just database schema that defines the data, you should try your best to validate data on input source, mostly commonly used one is Form
. Django form has very good api to verify data, so I suggest spending time on that instead of using pre_save
signal. That would also make debugging a lot easier.
Upvotes: 7