Сообщение об ошибке валидации при настройке 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')]}]}]}