Сообщение об ошибке валидации при настройке Django

У меня есть следующие определения сериализатора, которые проверяют полезную нагрузку запроса:

# diagnosis serializer
class ICD10Serializer(serializers.Serializer):
    icd_10 = serializers.IntegerField(required=True, allow_null=False)

class DetailsSerializer(serializers.Serializer):
    diagnosis_details = ICD10Serializer(many=True)

class ChartUpdateSerializer(serializers.Serializer):
    diagnosis = DetailsSerializer(many=True)

Использование:

payload = ChartUpdateSerializer(data=request.data)
if not payload.is_valid():
   raise serializers.ValidationError(payload.errors)

При этом выдается сообщение об ошибке валидации в следующем формате:

{
    "diagnosis": [
        {
            "diagnosisDetails": [
                {}, <- valid
                {}, <- valid
                {}, <- valid
                {}, <- valid
                {
                    "icd10": [
                        "This field may not be null."
                    ]
                }
            ]
        }
    ]
}

Здесь {} также отображается для валидных. Можем ли мы просто выдать ошибку валидации для недействительных? Или лучше даже, если мы можем знать, какое поле и сообщение, чтобы можно было сгенерировать пользовательское сообщение.

Если вам это действительно нужно, вы можете использовать, например, такой скрипт:

def remove_empty_objects(errors, _parent_pos=None):
    def filter_empty_list_objects():
        for pos, list_value in enumerate(value, 1):
            if not list_value:
                continue

            if isinstance(list_value, ErrorDetail):
                msg = f' Init array position: {_parent_pos!r}'
                yield ErrorDetail(
                    string=str(list_value) + msg,
                    code=list_value.code,
                )
            else:
                yield remove_empty_objects(errors=list_value, _parent_pos=pos)

    for key, value in errors.items():
        if isinstance(value, list):
            errors[key] = [*filter_empty_list_objects()]
    return errors

Этот скрипт рекурсивно перебирает все объекты и удаляет пустые значения. Я также добавил сообщение, указывающее на позицию объекта в исходном массиве (обратите внимание, что здесь номер позиции начинается с 1, а не 0), чтобы избавиться от проблемы, о которой писал @willeM_ Van Onsem в комментариях. Но в целом вы можете полностью отменить сообщения, если вам это необходимо. Я не тестировал этот скрипт подробно, но для случая, который вы описали, он будет работать. Вот пример:

errors = {
    'diagnosis': [
        {'diagnosis_details': [
            {}, 
            {'icd_10': [ErrorDetail(string='This field may not be null.', code='null')]}, 
            {'icd_10': [ErrorDetail(string='This field may not be null.', code='null')]}, 
            {}, 
            {},
        ]}, 
        {'diagnosis_details': [
            {}, 
            {'icd_10': [ErrorDetail(string='This field may not be null.', code='null')]},
        ]}
    ]
}

result = remove_empty_objects(errors=errors)

{'diagnosis': [{'diagnosis_details': [{'icd_10': [ErrorDetail(string='This field may not be null. Init array position: 2', code='null')]},
                                      {'icd_10': [ErrorDetail(string='This field may not be null. Init array position: 3', code='null')]}]},
               {'diagnosis_details': [{'icd_10': [ErrorDetail(string='This field may not be null. Init array position: 2', code='null')]}]}]}
Вернуться на верх