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

Asked By: Tylzan

||

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

Answered By: Lucas Grugru

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.

Answered By: Masud Dipu
Categories: questions Tags: , ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.