128👍
OK, I figured it out from this answer.
You have to do something like this:
class Dog(models.Model):
bark_volume = models.DecimalField(...
unladen_speed = models.DecimalField(...
def clean_fields(self):
if self.bark_volume < 5:
raise ValidationError({'bark_volume': ["Must be louder!",]})
13👍
class Dog(models.Model):
bark_volume = models.DecimalField(...
unladen_speed = models.DecimalField(...
def clean(self):
if self.bark_volume < 5:
if not self._errors.has_key('bark_volume'):
from django.forms.util import ErrorList
self._errors['bark_volume'] = ErrorList()
self._errors['bark_volume'].append('must be louder!')
That works on forms, at least. Never tried it on the model itself, but the methodology should be the same. However, from the Django docs:
When you use a ModelForm, the call to is_valid() will perform these validation steps for all the fields that are included on the form. (See the ModelForm documentation for more information.) You should only need to call a model’s full_clean() method if you plan to handle validation errors yourself, or if you have excluded fields from the ModelForm that require validation.
And…
Note that full_clean() will not be called automatically when you call your model’s save() method, nor as a result of ModelForm validation. You’ll need to call it manually when you want to run model validation outside of a ModelForm.
So, basically, unless you have a really good reason to do field cleaning on the model, you should do it on the form instead. The code for that would look like:
class DogForm(forms.ModelForm):
def clean(self):
bark_volume = self.cleaned_data.get('bark_volume')
if bark_volume < 5:
if not self._errors.has_key('bark_volume'):
from django.forms.util import ErrorList
self._errors['bark_volume'] = ErrorList()
self._errors['bark_volume'].append('must be louder!')
return self.cleaned_data
And that will work, for sure.
- [Django]-Django test app error – Got an error creating the test database: permission denied to create database
- [Django]-Django REST Framework (DRF): Set current user id as field value
- [Django]-Django-allauth: Linking multiple social accounts to a single user
11👍
To note for anyone that may come across this with a newer version of Django – the clean_fields method from the accepted answer now requires an “exclude” param. Also – I believe the accepted answer is also missing a call to it’s super function. The final code that I used was:
def clean_fields(self, exclude=None):
super(Model, self).clean_fields(exclude)
if self.field_name and not self.field_name_required:
raise ValidationError({'field_name_required':["You selected a field, so field_name_required is required"]})
- [Django]-Django admin file upload with current model id
- [Django]-Django ModelForm for Many-to-Many fields
- [Django]-Raw SQL queries in Django views
7👍
abbreviated, from the django docs:
def clean(self):
data = self.cleaned_data
subject = data.get("subject")
if subject and "help" not in subject:
msg = "Must put 'help' in subject."
self.add_error('subject', msg)
return data
- [Django]-How to solve "Page not found (404)" error in Django?
- [Django]-Iterate over model instance field names and values in template
- [Django]-How to get getting base_url in django template
6👍
Use a clean_
method that is specific to the field:
class DogForm(forms.ModelForm):
class Meta:
model = Dog
def clean_bark_volume(self):
if self.cleaned_data['bark_volume'] < 5:
raise ValidationError("must be louder!")
See the clean<fieldname>
part of the Form Validation page. Also, make sure to use cleaned_data
instead of the form field itself; the latter may have old data. Finally, do this on the form and not the model.
- [Django]-Why is __init__ module in django project loaded twice
- [Django]-Catching DoesNotExist exception in a custom manager in Django
- [Django]-What is pip install -q -e . for in this Travis-CI build tutorial?
6👍
The simplest way to validate this particular case would be:
from django.core.validators import MinValueValidator
from django.utils.translation import ugettext_lazy as _
class Dog(models.Model):
bark_volume = models.DecimalField(
..., validators=[MinValueValidator(5, message=_("Must be louder!"))]
Django’s documentation about validators: https://docs.djangoproject.com/en/dev/ref/validators/
- [Django]-Error: No module named psycopg2.extensions
- [Django]-Uninstall Django completely
- [Django]-Do we need to upload virtual env on github too?