Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
675 views
in Technique[技术] by (71.8m points)

Django Rest Framework Serializer - How to allow optional fields to be ignored when invalid?

I have a use case targeting developers sending extra data to my API. I want my API to have a strict typing system via Django Rest Framework Serializer validation. However, if a user sends partially invalid data, I want to ignore that data if the field is optional rather than return a 400 response. For example, consider a key-value tags field

tags = serializers.DictField(child=serializers.CharField(), required=False)

Valid data for the tags field might look like {"foo": "bar"}. Invalid data could look like {"foo": "bar", "invalid": {{"some": "object"}} as the value for "invalid" is an object and not a string. DRF is_valid will consider this invalid. validated_data will not be populated.

> serializer.is_valid()
False
> serializer.validated_data
{}

Because this field is not required and other tags might be valid, I'd want this returned instead

> serializer.is_valid()
True
> serializer.validated_data
{'another_field': 'a', 'tags': [{'foo': 'bar']}

Is there a way to make optional fields ignore invalid data instead of making the entire serializer invalid while still using a Django Rest Framework serializer and benefiting from the other validation and normalization performed?

question from:https://stackoverflow.com/questions/65848389/django-rest-framework-serializer-how-to-allow-optional-fields-to-be-ignored-wh

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

You can create a custom field by overriding the run_child_validation(...) method

class CustomDictField(serializers.DictField):
    def run_child_validation(self, data):
        result = {}
        for key, value in data.items():
            key = str(key)

            try:
                result[key] = self.child.run_validation(value)
            except serializers.ValidationError:
                pass
            
        return result

Example

In [2]: data = {"test": {"foo": "bar", "invalid": {"some": "object"}}}

In [3]: s = TestSerializer(data=data)

In [4]: s.is_valid()
Out[4]: True

In [5]: s.validated_data
Out[5]: OrderedDict([('test', {'foo': 'bar'})])

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...