I have a cornice API with a view that has validators and a colander schema. I can't get access to colander validated data (request.validated
) in my validator.
I pass my data through colander. My colander schema looks something like this:
from colander import (
MappingSchema,
SchemaNode,
String
)
class UserSchemaRecord(MappingSchema):
username = SchemaNode(String())
password = SchemaNode(String())
class UserSchema(MappingSchema):
user = UserSchemaRecord()
It adds a sanitized version of the request data into request.validated['user']
that I can then access in my view like this.
@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}
However, I also need to check that the request provides a unique username and return an error if the username is already taken. I'd like to do this with a validator (valid_new_username
) but when I try to access request.validated['user']
in my validator the data aren't there.
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
It looks like the validator is called before the data have been extracted. I don't really want to access the request json_body data directly before passing them through colander. Is there a way I can change the ordering of the schema/validator?
The alternative is to do the checking directly in my view callable. Is that a good option? Are validators not supposed to work with colander validated data?