Нужен лучший способ валидации полей в теле запроса 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
    }
}
Вернуться на верх