pyramid/cornice 验证器和漏勺模式

pyramid/cornice validators and colander schema

我有一个檐口 API,其视图具有验证器和漏勺架构。我无法在我的验证器中访问漏勺验证数据 (request.validated)。

我通过漏勺传递数据。我的漏勺架构看起来像这样:

from colander import (
    MappingSchema,
    SchemaNode,
    String
)

class UserSchemaRecord(MappingSchema):
    username = SchemaNode(String())
    password = SchemaNode(String())

class UserSchema(MappingSchema):
    user = UserSchemaRecord()

它将请求数据的净化版本添加到 request.validated['user'] 中,然后我可以像这样在我的视图中访问它。

@view(renderer='json', validators=(valid_token, valid_new_username), schema=UserSchema)
def collection_post(self):
    """Adds a new user"""
    user_data = self.request.validated['user']
    user = UserModel(**user_data)
    DBSession.add(user)
    DBSession.flush()
    return {'user': user}

但是,我还需要检查请求是否提供了唯一的用户名,return 如果用户名已被占用,则会出现错误。我想使用验证器 (valid_new_username) 执行此操作,但是当我尝试在我的验证器中访问 request.validated['user'] 时,数据不存在。

def valid_new_username(request):
    user = request.validated['user'] # this line fails with a KeyError
    username = user['username']
    if UserModel.get_by_username(username):
        request.errors.add('body', 'username', "User '%s' already exists!" % username)
        request.errors.status = 409 # conflict

看起来在提取数据之前调用了验证程序。我真的不想在通过漏勺传递请求 json_body 数据之前直接访问它们。有什么办法可以更改 schema/validator 的顺序吗?

另一种方法是直接在我的可调用视图中进行检查。这是一个好的选择吗?验证器不应该使用漏勺验证数据吗?

不确定这是不是你的问题,但如果数据一开始就无效(漏勺发现错误),那么它将无法作为 request.validated['key'] 在验证者。

如果你只想在数据通过漏勺验证时应用验证器,你可以使用这样的装饰器。

def when_valid(validator):
    """Decorator for validation functions.
    Only try validation if no errors already.

    """
    def inner(request):
        if len(request.errors) > 0:
            return
        validator(request)
    return inner

@when_valid
def valid_new_username(request):
    pass # your validation here