How to do model data validation in django
Question:
I would like when creating and editing a product to validate the data directly in the model in adminpanel and forms and if validated return an error more or less like this:
models.py
class Book(Product):
GENRE_CHOICES = (
('Fantasy', 'Fantasy'),
('Sci-Fi', 'Sci-Fi'),
('Romance', 'Romance'),
('Historical Novel', 'Historical Novel'),
('Horror', 'Horror'),
('Criminal', 'Criminal'),
('Biography', 'Biography'),
)
author = models.CharField(max_length=100, null=False, blank=False)
isbn = models.CharField(max_length=100, null=False, blank=False, unique=True)
genre = models.CharField(max_length=100, choices=GENRE_CHOICES, null=False, blank=False)
def save(self):
try:
Book.objects.get(author=self.author, title=self.title, genre=self.genre)
raise ValueError("Author, title and genre must not be repeated")
except ObjectDoesNotExist:
super().save()
Author, title and genre cannot repeat as tuple.
Of course, overriding the save() method throws me an error when I try to use the already created model to add to the cart, etc….
Please help me on how I should do it. Thank you all
Answers:
There are two solution for specific model validation.
You can override full_clean
method in your model:
class Book(Product):
[...]
def full_clean(self):
if Book.objects.filter(author=self.author, title=self.title, genre=self.genre).exists():
raise ValueError("Author, title and genre must not be repeated")
def save(self):
...
Documentation about model validation: https://docs.djangoproject.com/en/4.1/ref/models/instances/#validating-objects
But, for your specific cases, you can add directly UniqueContrstraint in meta model:
class Book():
...
class Meta:
...
constraints = [
UniqueConstraint(fields=['title', 'author', 'genre'], name='unique_book')
]
documentation about model constraints: https://docs.djangoproject.com/fr/4.1/ref/models/constraints/#fields
If you want three fields unique record, you can do it easily using unique_together in class Meta. You can try this code snippet:
class Meta:
unique_together = [‘author’, ‘title’, ‘genre’]
To check Django official documentation click here.
I would like when creating and editing a product to validate the data directly in the model in adminpanel and forms and if validated return an error more or less like this:
models.py
class Book(Product):
GENRE_CHOICES = (
('Fantasy', 'Fantasy'),
('Sci-Fi', 'Sci-Fi'),
('Romance', 'Romance'),
('Historical Novel', 'Historical Novel'),
('Horror', 'Horror'),
('Criminal', 'Criminal'),
('Biography', 'Biography'),
)
author = models.CharField(max_length=100, null=False, blank=False)
isbn = models.CharField(max_length=100, null=False, blank=False, unique=True)
genre = models.CharField(max_length=100, choices=GENRE_CHOICES, null=False, blank=False)
def save(self):
try:
Book.objects.get(author=self.author, title=self.title, genre=self.genre)
raise ValueError("Author, title and genre must not be repeated")
except ObjectDoesNotExist:
super().save()
Author, title and genre cannot repeat as tuple.
Of course, overriding the save() method throws me an error when I try to use the already created model to add to the cart, etc….
Please help me on how I should do it. Thank you all
There are two solution for specific model validation.
You can override full_clean
method in your model:
class Book(Product):
[...]
def full_clean(self):
if Book.objects.filter(author=self.author, title=self.title, genre=self.genre).exists():
raise ValueError("Author, title and genre must not be repeated")
def save(self):
...
Documentation about model validation: https://docs.djangoproject.com/en/4.1/ref/models/instances/#validating-objects
But, for your specific cases, you can add directly UniqueContrstraint in meta model:
class Book():
...
class Meta:
...
constraints = [
UniqueConstraint(fields=['title', 'author', 'genre'], name='unique_book')
]
documentation about model constraints: https://docs.djangoproject.com/fr/4.1/ref/models/constraints/#fields
If you want three fields unique record, you can do it easily using unique_together in class Meta. You can try this code snippet:
class Meta:
unique_together = [‘author’, ‘title’, ‘genre’]
To check Django official documentation click here.