Amit Yadav
Amit Yadav

Reputation: 59

Django Model conditional Validations

i have made an api on which a customer is sending his/her details for payment by making post request, so need to validate this data on model level,How can i validate a model field by comparing it to the other model fields For example:

models.py
Orders(models.Model):
   amount = models.DecimalField(max_digits=19, decimal_places=4)
   currency = models.CharField(max_length=3,choices=[('INR','INR')]) more choices are to be added 
   payee_pan = models.CharField(max_length=10)

Validation required : payee_pan must be present if currency is 'INR' and amount is greater than 50000. in order to validate it i am using model.full_clean() while saving the the model object in views.py

views.py
    try:
        orders.full_clean()
    except ValidationError:
        return Response({"Error message":"invalid request body"})
    else:
        orders.save()

i would really appreciate if someone helps me in this as m stuck at this point for so long.enter code here

Upvotes: 0

Views: 1256

Answers (2)

Gabriel Rockson
Gabriel Rockson

Reputation: 141

from django.db import models
from django.core.exceptions import ValidationError


class Orders(models.Model):
    amount = models.DecimalField(max_digits=19, decimal_places=4)
    currency = models.CharField(max_length=3, choices=[('INR','INR')]) # more choices are to be added 
    payee_pan = models.CharField(max_length=10)

    class Meta:
        verbose_name = "Order"
        verbose_name_plural = "Orders"

    def clean(self):
        if self.currency == 'INR' and self.amount > 50000 and not self.payee_pan:
            raise ValidationError(
                {"payee_pan": "Payee Pan field is required"}
            )
    
    def save(self, *args, **kwargs):
        self.full_clean()
        return super().save(*args, **kwargs)

You can remove the try-except block in your views. Calling the save() method will invoke the full_clean() method under the hood which will call any validation hooks.

Upvotes: 0

Abdul Aziz Barkat
Abdul Aziz Barkat

Reputation: 21787

You can perform such validation by overriding the clean method on the model (Reference Validating objects [Django docs]):

from django.core.exceptions import ValidationError
from django.utils.translation import gettext_lazy as _


class Orders(models.Model):
    amount = models.DecimalField(max_digits=19, decimal_places=4)
    currency = models.CharField(max_length=3,choices=[('INR','INR')])
    payee_pan = models.CharField(max_length=10)
    
    def clean(self):
        if self.currency == 'INR' and self.amount > 50000 and not self.payee_pan:
            raise ValidationError(_('Payee Pan is required'))

Note: Ideally model names are supposed to be singular (If you check the verbose name plural for your model it ends up as Orderss with an extra s currently). Hence it should be Order instead of Orders.

Upvotes: 0

Related Questions