2

Well I am building this django rest api where my users can send some data and I save them into the db. There I need to validate the data send by them prior to saving them to the db.

I have already added validators like,

def validate(self, value):
    UnitOfMeasureName = ["Each", "Grams", "Ounces", "Pounds", "Kilograms", "Metric Tons"]
    if value in UnitOfMeasureName:
        return True
    else:
        return ValidationError('Invalid')

inside the serializers but there are several such validations to be achieved for each serializer. So I am searching for a way where I can use one function for all those validations. I am thinking of using of args and kwargs but have no idea how to proceed. I was thinking something like:

def validate_all(*args, **kwargs):
    if not validation_1:
        validation_error = {add the error messsage to the dic}
    if not validation_2:
        ...
    if not validation_3:
        ...
    return validation_error

An example serializer:

class TransSerializer(serializers.ModelSerializer):
    def validate(self, data):
        if not data['unitofmeasurename'] in UnitOfMeasureName:
            raise serializers.ValidationError("INVALID")
        return data

    class Meta:
        model = Trans
        fields = ('unitofmeasurename','name')

So in another serializer I need to check the validation for both 'unitofmeasurename' and 'name'. Is there a way to achieve this using only one common function? Any ideas please. Thanks in advance.

Pabasara Ranathunga
  • 160
  • 1
  • 2
  • 18

1 Answers1

1

You can do something like:

models

from your_app.mixins import ValidationMixin

class YourSerializer(ModelSerializer, ValidationMixin):

    def create(self, validated_data):
        # First check
        self.raise_if_something_wrong(validated_data['value'])

        # Second check
        self.get_object_if_exist(validated_data['title'])

        # This will happen ONLY if your previous check's were ok
        your_model = YourModel.objects.create(
            **validated_data
        )
        return your_model

mixins

from django.conf import settings
from rest_framework.serializers import ValidationError

class ValidationMixin:

    def raise_if_something_wrong(self, value):
        if value not in settings.UNIT_OF_MEASURE_NAME:
            raise ValidationError(
                'Invalid'
            )
        else:
            pass

    def get_object_if_exist(self, obj_title):
        try:
            return YourModel.objects.get(title=obj_title)
        except YourModel.DoesNotExist:
            raise ValidationError(
                'Cant get that object'
            )

settings

Also add this to your project's main settings.py file, keep it like a tuple:

UNIT_OF_MEASURE_NAME = (
    'Each',
    'Grams',
    'Ounces',
    'Pounds',
    'Kilograms',
    'Metric Tons'
)

As a result you will be able to use ValidationMixin wherever you want to validate data, and keep validation logic in one place.

inmate_37
  • 1,218
  • 4
  • 19
  • 33