2014-01-24 3 views
0

я следовал этому example, но я изменил его немного, чтобы удовлетворить мой проектDeform Inter-Field Validation не выделяя поле

Это то, что у меня есть:

class AgentFormValidation(object):   

    def __init__(self, context, request): 
     self.context = context 
     self.request = request 

    def __call__(self, form, value): 
     number = value['identity_information']['number'] 
     print validateID(number) 
     type = value['identity_information']['type'] 
     q = sqlahelper.get_session().query(Agents.id_number).filter(Agents.id_number == number).first() 

     if type == "IDNumber": 
      if not validateID(number): 
       if q: 
        exc = colander.Invalid(form["identity_information"], "ID Number %s already exists in Database" % number) 
        exc.number = "ID Number already exists " 
        raise exc 
      else: 
       exc = colander.Invalid(form["identity_information"], "ID Number %s is not a valid SA ID Number" % number) 
       exc.number = "Invalid ID number" 
       raise exc 
     elif type == "Passport": 
      if q: 
       exc = colander.Invalid(form["identity_information"], "Passport number %s already exists in Database" % number) 
       exc.number = "Passport number already exists" 
       raise exc 


def gen_agent_schema_form(self): 
     _but = ('create agent',) 
     _title = "Create Agent" 
     if not self.context.__is_new__: 
      _but = ('update agent',) 
      _title = "Agent Details" 
     deals = [] 
     if self.context.ou: 
      deals = [(deal.id, str(deal)) for deal in self.context.ou[0].org_deals] 

     schema = Agent(validator=AgentFormValidation(self.context, self.request), title=_title).bind(deals=deals) 
     form = Form(schema, buttons=_but) 
     return schema, form 

Валидация работает просто отлично. Он просто не хочет выделять элемент.

Когда я заменяю:

exc.number = "ID Number already exists" 

с

exc['number'] = "ID Number already exists" 

Это делает блик, но Выделяет самый первый элемент на форме, которая является first_name, который также является неправильным.

Я чувствую, что мне не хватает чего-то маленького.

UPDATE

Так что я играл немного, когда я делаю:

exc = colander.Invalid(form, "ID Number %s already exists in Database" % number) 
    exc["identity_information"] = "ID Number already exists " 
    raise exc 

Я получаю предупреждение окно сообщения (не JS оповещения) выше соответствующее поле:

image of what I am getting

Вместо этого мне нужно выделить поле, как в примере выше.

+0

Почему голосующий ???????? – Renier

ответ

2

В вашем пользовательском валидаторе вы всегда передаете форму в качестве первого параметра для colander.Invalid(). Таким образом, вы добавляете сообщения проверки в верхнюю часть формы, но вы не вызываете выделение узлов или элементов схемы. Начните использовать простые валидаторы, работающие над одним узлом/элементом схемы.

exc = colander.Invalid(form["identity_information"], "ID Number %s already exists in Database" % number) 

Во всяком случае, я не вижу ясного требования к межведомственной проверке. Вместо применения сложного валидатора на основе класса на Схеме агента вы могли бы использовать доступные проверки валидатора коллаборатора или создавать собственные валидаторы на каждом узле схемы агента, тем самым сохраняя валидаторы как можно более простыми. Ваша текущая реализация валидатора слишком много касается слишком большого числа случаев использования.

Я предположил, что у вас есть два разных варианта использования: регистрация и еще одна связанная с агентом задача. Придумывая разные схемы, я могу сохранить валидность для узлов схемы и использования. Уникальность идентификатора может быть важна только при создании материала с формой добавления/создания, в форме обновления пользователи могут не изменять все эти значения, но ограниченный набор личной информации.

Основная идея заключается в использовании валидаторов узлов схемы для получения сообщений проверки на узлах схемы. В особых случаях применяются валидаторы уровня формы (регистрация агента).

Ваш пример использования иллюстрирует область проверки формы. Класс, который проверяет входные данные форм на схемы и обрабатывает темы, связанные с сохранением (уникальность первичного ключа), делает слишком много. Оба должны быть инкапсулированы для развития отдельно.Ваши бизнес-правила будут меняться со временем, таблица базы данных всегда будет требовать уникальности для первичных ключей.

Схемы

import colander 

class AgentRegistration(colander.Schema): 
    """schema for agent registration with email validation 

    Note the form validator is invoked only if none of the individual field validators raise an error. 
    """ 

    first_name = colander.SchemaNode(colander.String()) 
    number = colander.SchemaNode(colander.Integer(), validator=can_register_agent) 
    email = colander.SchemaNode(colander.String(), validator=colander.Email()) 
    verify_email = colander.SchemaNode(colander.String(), validator=colander.Email()) 

    validator = verify_email_validator 


class AgentDeals(colander.Schema): 
    "schema for managing agent deals" 
    first_name = colander.SchemaNode(colander.String()) 
    number = colander.SchemaNode(colander.Integer(), validator=validateID) 
    email = colander.SchemaNode(colander.String(), validator=colander.Email()) 

схемы Validators

def agent_unique(node, value): 
    "validate uniqueness of value in database table Agents" 
    if sqlahelper.get_session().query(Agents.id_number).filter(Agents.id_number == value).first() 
     raise Invalid(node, 
        'ID Number %r is already given to another agent. Please change it' % value) 

def valid_SA_ID(node, value): 
    "validates SA ID Number - just a copy of your requirement calling your custom function" 
    if not validateID(value): 
     raise Invalid(node, 
        'SA ID Number %r is not valid.' % value) 

def can_register_agent(node, value): 
    "ensure Agent ID Number is a valid and not already existing in database" 
    valid_SA_ID(node, value) 
    agent_unique(node, value) 

def verify_email_validator(form, values): 
    """schema level validator with access to all values 

    validates emails are same 
    validation messages are displayed on top of form""" 

    if values['email'] != values['verify_email']: 
     raise colander.Invalid(form, 'Email values do not match.') 

Форма

class AgentRegistrationView(object) 

    def __init__(self, request): 
     """Set some common variables needed for each view. 
     """ 
     self.request = request 
     self.context = request.context 

    @view_config(route_name='add_agent', permission='admin', renderer='add_agent.mako') 
    def add_agent(self): 
     """return form to create new agents 

     may be we do not need to bind any deals data here""" 

     schema = AgentRegistration() 
     form = deform.Form(schema, action=self.request.route_url('add_agent'), buttons=('Add Agent','Cancel')) 


class AgentDealsView(object) 

    def __init__(self, request): 
     """Set some common variables needed for each view. 
     """ 
     self.request = request 
     self.context = request.context 


    def get_deals(self) 
     """return deals to be bound to Agent Schema""" 
     if self.context.ou: 
      return [(deal.id, str(deal)) for deal in self.context.ou[0].org_deals] 


    @view_config(route_name='edit_agent' permission='edit', renderer='edit_agent.mako') 
    def edit_agent(self): 

     # we bind deals data to form 
     schema = AgentDeals().bind(deals=self.get_deals()) 
     form = deform.Form(schema, action=self.request.route_url('edit_agent'), buttons=('Save','Cancel')) 

Список литературы

Кроме того, вы можете быть заинтересованы в ColanderAlchemy, но это добавляет еще один уровень абстракции. На самом деле, я не рекомендую его вам.

+0

Спасибо за ваш ответ. Мне не нужно решать, какие «сайты-пакеты мы используем, я просто код»:), как для вашего предложения, при запуске отладчика, он работает, но я не вижу ничего, что связано с моей проблемой. – Renier

+0

Спасибо за помощь ':)' – Renier

Смежные вопросы