Нужен лучший способ валидации полей в теле запроса django в зависимости от конкретного значения поля
Требуется проверить поля тела в api запросе в зависимости от другого поля.
Например: в данных запроса есть поле:
action
Если действие равно deactivate
то никакое другое поле не должно присутствовать в теле данных, однако если действие - это что-то другое, мы хотим разрешить обновление и других полей, таких как name
.
в настоящее время у нас есть валидация, где мы перебираем ключи словаря и сравниваем, как показано ниже:
expected_keys = ['client_updated', 'updated_by', 'actions']
if key not in expected_keys:
raise ValidationError("Deactivation action does not allow {} to be updated".format(key))
Просто хотел узнать, есть ли лучший способ обработки через django или django rest framework, с несколько меньшим количеством кодирования.
Вы можете попробовать использовать JSON-схему для определения поведения, а затем проверять вводимые данные в соответствии с этой схемой при отправке запроса. В случае положительного ответа возвращается код ответа 2xx и выполняется действие, в противном случае - код ответа 400 и возвращается ошибка, возникшая при проверке.
Вот пример условной проверки с использованием If, then
. Это будет работать только с JSON Schema draft-07 или более поздней версией.
Суть в том, что вы можете проверить const
(константное) значение свойства и проверить, соответствует ли оно вашему условию, если соответствует, то вы можете установить свойства action
с помощью additionalProperties: false
, поскольку ваше условие гласит, что если actions=deactivate
, то никакие другие свойства не разрешены. Это немного многословно, потому что вам нужно переопределить properties
снова внутри then
, но это делает свою работу. Условие if
будет иметь значение true
только в случае actions=deactivate
, в противном случае определение схемы остается таким же, как и первоначально определенное до if
.
{
"$schema": "http://json-schema.org/draft-07/schema#",
"type": "object",
"properties": {
"actions": {
"type": "string"
},
"client_updated": {
"type": "string"
},
"updated_by": {
"type": "string"
},
"name": {
"type": "string"
}
},
"if": {
"properties": {
"actions": {
"const": "deactivate"
}
}
},
"then": {
"properties": {
"actions": {
"type": "string"
}
},
"additionalProperties": false
}
}