Проверка многих полей, как они были одним? - PullRequest
4 голосов
/ 08 февраля 2012

Мой ввод довольно странно отформатирован, но в соответствии со спецификацией:

enter image description here

Пользователь должен ввести идентификатор в 4 поля (!), Где идентификатор - это форма 460 000 005 001, где 46 - код страны, а правая часть - идентификатор приложения пользователя. Теперь я хочу добавить проверку в это поле, но я не могу сделать это с помощью wtforms. Вот мой класс формы:

class RegisterWTForm(Form):
    soc_sec = TextField(_('Soc security number'),  [validators.Regexp('^[0-9]+$',
                      message=_('This is not a social security number, please see the example and try again'
                      )), validators.Required(message=_('Social security number is required')), unique_soc_sec], widget=MyTextInput())
    email = TextField(_('Email'),
                      [validators.Required(message=_('Email is required'
                      )),
                      validators.Email(message=_('Your email is invalid'
                      ))], widget=MyTextInput())

    def validate_soc_sec(form, field):
        if len(field.data) != 10:
            raise ValidationError(_('Soc sec must be 10 characters'
                                  ))
    def validate_email(form, field):
        if len(field.data) > 60:
            raise ValidationError(_('Email must be less than 60 characters'
                                  ))

А вот как я теперь использую переменные, они не являются частью WTForm, а являются обычными параметрами http:

def post(self):
    Log1 = self.request.POST.get('Log1')
    Log2 = self.request.POST.get('Log2')
    Log3 = self.request.POST.get('Log3')
    Log4 = self.request.POST.get('Log4')    
    form = RegisterWTForm(self.request.params)
    if form.validate():
        logging.info('validated successfully')
    else:
        logging.info('form did not validate')
        self.render_jinja('register.html', form=form, Log1=Log1, Log2=Log2, Log3=Log3, Log4=Log4 )
        return ''
    email = self.request.POST.get('email')

    sponsor_id = '%s%s%s' % (Log2, Log3, Log4)
    if sponsor_id:
        user = User.get_by_id(long(sponsor_id))
    else:
        return 'Sponsor with sponsor id %s does not exist' % sponsor_id
    if not user:
            return 'Sponsor with sponsor id %s does not exist' % sponsor_id

    # make a token for a one-time login link that sets the password
    # Passing password_raw=password so password will be hashed
    # Returns a tuple, where first value is BOOL. If True ok, If False no new user is created

    user = self.auth.store.user_model.create_user(email)

Есть ли способ добавить мои 4 переменные как одну переменную в мою WTForm и добавить туда проверку, или я должен сделать свою собственную проверку для этих полей? Для других моих полей я сделал их с красной рамкой и красным текстом, если поле не проходит проверку, и я хотел бы сделать то же самое здесь, но это будет много логики на уровне представления, если я не могу сделать это с помощью класса формы и добавить код в шаблон. Можете ли вы предложить, что делать?

Спасибо

Обновление

Я мог бы создать FormField, который комбинирует поля, но они не отображаются правильно, и мне не нужны все 4 проверки. Может быть, вы можете сказать мне больше, как сделать так, как я хочу?

class SponsorWTForm(Form):
    log1 = IntegerField('log1', [validators.required()])
    log2 = IntegerField('log2', [validators.required()])
    log3 = IntegerField('log3', [validators.required()])
    log4 = IntegerField('log4', [validators.required()])

class RegisterWTForm(Form):
    sponsor_id = FormField(SponsorWTForm)

...

enter image description here

1 Ответ

5 голосов
/ 09 февраля 2012

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

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

return HTMLString(u' '.join([subfield() for subfield in field]))

может удовлетворить ваши потребности. Затем поместите widget=SingleLineWidget() (или как вы называете класс вашего виджета) в аргументы конструктора FormField.

Немного не по теме, соответствующий способ сделать это в Django Forms несколько иной: вы определяете пользовательские методы очистки и проверки , которые преобразуют ваши данные (т.е. в этом случае, объединяя 4 поля ID в один).

...