Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Get value of another field in Field level Validation in DRF

I am using Field level Validation in my serializer and I have situation where I need value of first field while validating second field. I know in object level validation I can have access to that but my serailzer have many=True and in object level validation I cannot tell client side which iteration have raised the error.

Serailzer :

class Keys_Serializer(serializers.Serializer):
    """
    """
    key_id = serializers.IntegerField(required=True)
    key_name = serializers.CharField(required=True)
    value_id = serializers.IntegerField(required=False)

    def validate_key_id(self, value):
        """
        validate key id
        """
         *** validate key_id here ***
        return value

    def validate_value_id(self, value):
        """
        validate value_id w.r.t key_id
        """
         *** I need key_id of current iteration here so that I can validate value_id. ***
        return value

Is there any way of accessing the value of key_id in value_id validation.

like image 627
user5594493 Avatar asked Apr 11 '16 13:04

user5594493


People also ask

How to perform details field validation in DRF?

Show activity on this post. DRF's serializers provide field level validation option. You can perform details field validation by implementing validate_details method: Show activity on this post.

How do you validate a field in access?

Access Field Validation Rule Based on Value in Another Field – When you create a field in an MS Access table you can create a validation rule for it. The rule might for example restrict entry to numeric values in a range or dates in a range. Sometimes you want the rule to refer to a value in another field.

Can you not refer to another field in a Validation rule?

This basically tells you you cannot refer to another field in your validation rule. To achieve this you will need to enter the rule in the table’s property sheet. Open the property sheet and you will find a validation rule and a validation text property for the table: enter your rule there.

How to validate jsonfiled on Django model level?

DRF's serializers provide field level validation option. You can perform details field validation by implementing validate_details method: Show activity on this post. The other way around is to validate JSONFiled on Django models level, you can use jsonschema package.


2 Answers

No that is not possible. If you need to access more than one value you have to use the Object-level validation (see docs):

class Keys_Serializer(serializers.Serializer):

    key_id = serializers.IntegerField(required=True)
    key_name = serializers.CharField(required=True)
    value_id = serializers.IntegerField(required=False)

    def validate(self, data):
        # here you can access all values
        key_id = data['key_id']
        value_id = data['value_id']
        # perform you validation
        if key_id != value_id:
            raise serializers.ValidationError("key_id must be equal to value_id")
        return data
like image 93
ilse2005 Avatar answered Sep 23 '22 15:09

ilse2005


I dug around codebase of drf a little bit. You can get values of all fields using following approach. This way you can throw serialization error as {'my_field':'error message} instead of {'non_field_error':'error message'}

def validate_myfield(self, value):
   data = self.get_initial() # data for all the fields
   #do your validation

However, if you wish to do it for ListSerializer, i.e for serializer = serializer_class(many=True), this won't work. You will get list of empty values. In that scenario, you could write your validations in def validate function and to avoid non_field_errors in your serialization error, you can raise ValidationError with error message as a dictionary instead of string.

def validate(self, data):
    # do your validation
    raise serializers.ValidationError({"your_field": "error_message"})
like image 31
Sagar Adhikari Avatar answered Sep 22 '22 15:09

Sagar Adhikari