Dado un modelo existente para validar, como la de abajo (pero podría ser un simple diccionario o cualquier estructura de datos desde pyvaru no hace ninguna suposición sobre los datos formato):
class User:
def __init__(self, first_name: str, last_name: str, date_of_birth: datetime, sex: str):
self.first_name = first_name
self.last_name = last_name
self.date_of_birth = date_of_birth
self.sex = sex
tenemos que definir un validador, implementando el método get_rules() y para cada campo que queremos validar tenemos que proporcionar una o más regla (s) adecuado.
from pyvaru import Validator
from pyvaru.rules import TypeRule, FullStringRule, ChoiceRule, PastDateRule
class UserValidator(Validator):
def get_rules(self) -> list:
user = self.data # type: User
return [
TypeRule(apply_to=user,
label='User',
valid_type=User,
error_message='User must be an instance of user model.',
stop_if_invalid=True),
FullStringRule(user.first_name, 'First name'),
FullStringRule(user.last_name, 'Last name'),
ChoiceRule(user.sex, 'Sex', choices=('M', 'F')),
PastDateRule(user.date_of_birth, 'Date of birth')
]
Finalmente tenemos dos opciones en cuanto a cómo utilizar nuestro validador personalizado:
Como procesador de contexto:
with UserValidator(user):
# do whatever you want with your valid model
En este caso, el código dentro de la que se ejecutará sólo si el la validación tiene éxito; de lo contrario, se genera una ValidationException (que contiene una propiedad validation_result con el informe correspondiente).
Al invocar el método de validación() (que devuelve un ValidationResult)
validation = UserValidator(user).validate()
if validation.is_successful():
# do whatever you want with your valid model
else:
# you can take a proper action and access validation.errors
# in order to provide a useful message to the application user,
# write logs or whatever
Suponiendo que tenemos un ejemplo de un usuario configurado como la siguiente:
user = User(first_name=' ',
last_name=None,
date_of_birth=datetime(2020, 1, 1),
sex='unknown')
Mediante la ejecución de una validación con las reglas definidas previamente obtendremos un ValidationResult con los siguientes errores:
{
'First name': ['String is empty.'],
'Last name': ['Not a string.'],
'Sex': ['Value not found in available choices.'],
'Date of birth': ['Not a past date.']
}
No estoy muy familiarizado con esto, pero creo que es posible que desee utilizar un ORM (consulte http://stackoverflow.com/questions/2781682/mongodb-orm-for-python), aunque perdería el flexibilidad de una base de datos NoSQL. –
Gracias. Soy consciente de la posibilidad de usar un ORM, pero en este caso quiero manipular directamente la base de datos MongoDB. – anujkk
https://github.com/nicolaiarocci/cerberus/. Me gusta voluptuoso pero ahora prefiero Cerberus. Todas las reglas se pueden declarar en un archivo yaml legible para humanos en lugar de la necesidad de callables en voluptuosas y otras bibliotecas. – chishaku