Nested validation in Django Rest Framework

倖福魔咒の 提交于 2021-02-10 06:54:41

问题


Using django rest framework I want to validate fields.

Correct input request:

{
   test_field_a: {test_field_c: 25}, 
   test_field_b: {}
}

My serializers.py (I don't have any associated models and the models.py itself):

from rest_framework import serializers
class TestSerializer(serializers.Serializer):
  test_field_a = serializers.JSONField(label='test_field_a', allow_null=False, required=True)
  test_field_b = serializers.JSONField(label='test_field_b', required=True)
  test_field_c = serializers.IntegerField(label='test_field_c)

Wrong input request (which should state that int field is required) :

{
   test_field_a: {test_field_c: 'wrong'}, 
   test_field_b: {}
} 

Now test_field_a and test_field_b are validated as required. But how to make validation of fields on different levels of the request? (in this case test_field_c)


回答1:


JSONField just checks that a field contains correct JSON structure. You need to do it plus check values from this JSON.

There are several ways to do it:

  1. You can write your own custom field type (it's nice if you are planning to do something similar in other serializers);
  2. You can change field validation (try something like this):

    from rest_framework import serializers
    
    class TestSerializer(serializers.Serializer)::
        test_field_a = serializers.JSONField(label='test_field_a', allow_null=False, required=True)
        test_field_b = serializers.JSONField(label='test_field_b', required=True)
    
        def validate_test_field_a(self, value):
            """
            Check that test_field_a .
            """
            if not isinstance(value.get('test_field_c'), int):
               raise serializers.ValidationError("Some error message")
           return value
    
  3. You can try nested validation:

    from rest_framework import serializers
    
    
    class Test1Serializer(serializers.Serializer):
        test_field_c = serializers.IntegerField(label='test_field_c')
    
    
    class TestSerializer(serializers.Serializer):
        test_field_a = Test1Serializer()
        test_field_b = serializers.JSONField(label='test_field_b', required=True)
    



回答2:


The serializer's JSONField does not have a validation for nested fields because it is not meant to nest explicitly declared fields and as far as I know, there is currently no way to specify a json schema to validate it. What you can do is validate the field yourself by declaring a validate_test_field_a validation method.

For example:

    def validate_test_field_a(self, value):
        if 'test_field_c' not in value:
            raise serializers.ValidationError('`test_field_c` is required')
        return value

Generally, if you find yourself needing to validate the nested type inside the JSONField, then it is a sign of bad architecture and you should consider using nested serializers instead. Same applies to using JSONField in the model



来源:https://stackoverflow.com/questions/53651167/nested-validation-in-django-rest-framework

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!