Helpex - Trao đổi & giúp đỡ Đăng nhập
30

Xác thực biểu mẫu của tôi đang hoạt động gần như hoàn tất, tôi chỉ có 2 trường hợp tôi không biết chính xác cách giải quyết: 1) Trường mật khẩu tất nhiên là bắt buộc nhưng tôi cũng cung cấp khả năng đăng nhập bằng tài khoản google hoặc facebook thông qua OAuth và sau đó tên được điền trước nhưng tôi loại bỏ trường mật khẩu hoàn toàn khỏi biểu mẫu là có một người dùng (google) hoặc một đối tượng người dùng facebook:

<tr><td>
  <br />        {% if user or current_user %}    {% else %} 

  <div class="labelform">
     {% filter capitalize %}{% trans %}password{% endtrans %}{% endfilter %}:
  </div>
      </td><td>  <div class="adinput">{{ form.password|safe }}{% trans %}Choose a password{% endtrans %}</div>{% endif %}

  </td></tr>

Vì vậy, đối với những người dùng này đã đăng nhập và trường mật khẩu không có ý nghĩa, tôi cần một số logic để làm cho trường đó có điều kiện là tùy chọn. Tôi đã nghĩ rằng tôi có thể có một biến cho logged_in + một phương thức trong lớp biểu mẫu của mình, chẳng hạn như sau:

class AdForm(Form):
    logged_in = False
    my_choices = [('1', _('VEHICLES')), ('2', _('Cars')), ('3', _('Bicycles'))]
    name = TextField(_('Name'), [validators.Required(message=_('Name is required'))], widget=MyTextInput())
    title = TextField(_('title'), [validators.Required(message=_('Subject is required'))], widget=MyTextInput())
    text = TextAreaField(_('Text'),[validators.Required(message=_('Text is required'))], widget=MyTextArea())
    phonenumber = TextField(_('Phone number'))
    phoneview = BooleanField(_('Display phone number on site'))
    price = TextField(_('Price'),[validators.Regexp('\d', message=_('This is not an integer number, please see the example and try again')),validators.Optional()] )
    password = PasswordField(_('Password'),[validators.Optional()], widget=PasswordInput())
    email = TextField(_('Email'), [validators.Required(message=_('Email is required')), validators.Email(message=_('Your email is invalid'))], widget=MyTextInput())
    category = SelectField(choices = my_choices, default = '1')

    def validate_name(form, field):
        if len(field.data) > 50:
            raise ValidationError(_('Name must be less than 50 characters'))

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

    def validate_price(form, field):
        if len(field.data) > 8:
            raise ValidationError(_('Price must be less than 9 integers'))

    def validate_password(form, field):
        if not logged_in and not field:
            raise ValidationError(_('Password is required'))

Liệu validate_password trên có hoạt động để đạt được hiệu quả mong muốn không? Có cách nào khác tốt hơn không? Một cách khác tôi có thể nghĩ là có 2 lớp biểu mẫu khác nhau và trong bài đăng http, tôi cài đặt lớp biểu mẫu đó phải là:

def post(self):
    if not current_user:
      form = AdForm(self.request.params)
    if current_user:
      form = AdUserForm(self.request.params)

Tôi cũng cần xác thực có điều kiện cho trường danh mục, khi một danh mục nhất định được chọn thì nhiều lựa chọn hơn sẽ xuất hiện và những lựa chọn này chỉ nên xác thực cho một danh mục cơ sở nhất định, ví dụ. người dùng chọn "Xe" và sau đó thông qua Ajax có thể chọn dữ liệu đăng ký và số dặm cho xe và các trường này là bắt buộc khi danh mục Xe đã được chọn.

Vì vậy, nó có thể là hai câu hỏi nhưng cả hai trường hợp đều liên quan đến cách tôi có thể tạo một trường "tùy chọn có điều kiện" hoặc "bắt buộc có điều kiện".

Hình thức của tôi trông như thế này

Làm cách nào để tạo một trường tùy chọn có điều kiện trong WTForms?

Và đối với người dùng đã đăng nhập, tôi điền trước tên và địa chỉ email và trường mật khẩu chỉ đơn giản là không được sử dụng, vì vậy trường mật khẩu không phù hợp là "tùy chọn" cũng như "bắt buộc", nó sẽ cần một cái gì đó như "tùy chọn có điều kiện" hoặc "bắt buộc có điều kiện . "

Làm cách nào để tạo một trường tùy chọn có điều kiện trong WTForms?

Cảm ơn vì bất kỳ câu trả lời hoặc nhận xét nào

30 hữu ích 0 bình luận 16k xem chia sẻ
70

Tôi không chắc điều này hoàn toàn phù hợp với nhu cầu của bạn, nhưng trước đây tôi đã sử dụng RequiredIftrình xác thực tùy chỉnh trên các trường, điều này làm cho trường bắt buộc nếu một trường khác có giá trị trong biểu mẫu ... ví dụ: trong múi giờ ngày giờ kịch bản, tôi có thể đặt trường múi giờ bắt buộc phải có giá trị nếu người dùng đã nhập ngày giờ.

class RequiredIf(Required):
    # a validator which makes a field required if
    # another field is set and has a truthy value

    def __init__(self, other_field_name, *args, **kwargs):
        self.other_field_name = other_field_name
        super(RequiredIf, self).__init__(*args, **kwargs)

    def __call__(self, form, field):
        other_field = form._fields.get(self.other_field_name)
        if other_field is None:
            raise Exception('no field named "%s" in form' % self.other_field_name)
        if bool(other_field.data):
            super(RequiredIf, self).__call__(form, field)

Hàm tạo lấy tên của trường khác kích hoạt việc yêu cầu trường này, như:

class DateTimeForm(Form):
    datetime = TextField()
    timezone = SelectField(choices=..., validators=[RequiredIf('datetime')])

Đây có thể là một điểm khởi đầu tốt để triển khai loại logic bạn cần.

70 hữu ích 3 bình luận chia sẻ
7

Tôi thấy câu hỏi này hữu ích và dựa trên câu trả lời của @dcrosta, tôi đã tạo một trình xác thực khác là tùy chọn. Lợi ích là bạn có thể kết hợp nó với các trình xác thực wtforms khác. Đây là trình xác thực tùy chọn của tôi sẽ kiểm tra một trường khác. Vì tôi cần kiểm tra giá trị của trường khác so với một số giá trị nhất định nên tôi đã thêm kiểm tra tùy chỉnh cho giá trị:

class OptionalIfFieldEqualTo(wtf.validators.Optional):
    # a validator which makes a field optional if
    # another field has a desired value

    def __init__(self, other_field_name, value, *args, **kwargs):
        self.other_field_name = other_field_name
        self.value = value
        super(OptionalIfFieldEqualTo, self).__init__(*args, **kwargs)

    def __call__(self, form, field):
        other_field = form._fields.get(self.other_field_name)
        if other_field is None:
            raise Exception('no field named "%s" in form' % self.other_field_name)
        if other_field.data == self.value:
            super(OptionalIfFieldEqualTo, self).__call__(form, field)
7 hữu ích 0 bình luận chia sẻ
5

Câu trả lời từ @dcrosta là tuyệt vời, nhưng tôi nghĩ một số điều đã thay đổi trong wtforms kể từ câu trả lời này. Kế thừa từ DataRequiredthêm một requiredthuộc tính vào trường biểu mẫu, vì vậy trình xác thực có điều kiện không bao giờ được gọi. Tôi đã thực hiện một thay đổi nhỏ đối với lớp từ @dcrosta hoạt động với wtforms 2.1. Điều này chỉ chạy field_flagsquá mức để xác thực trình duyệt không được thực hiện.

from wtforms.validators import DataRequired


class RequiredIf(DataRequired):
    """Validator which makes a field required if another field is set and has a truthy value.

    Sources:
        - http://wtforms.simplecodes.com/docs/1.0.1/validators.html
        - http://stackoverflow.com/questions/8463209/how-to-make-a-field-conditionally-optional-in-wtforms

    """
    field_flags = ('requiredif',)

    def __init__(self, other_field_name, message=None, *args, **kwargs):
        self.other_field_name = other_field_name
        self.message = message

    def __call__(self, form, field):
        other_field = form[self.other_field_name]
        if other_field is None:
            raise Exception('no field named "%s" in form' % self.other_field_name)
        if bool(other_field.data):
            super(RequiredIf, self).__call__(form, field)

Một giải pháp lý tưởng hơn sẽ quản lý để thực hiện xác thực trong trình duyệt, như hành vi hiện tại của DataRequired.

5 hữu ích 2 bình luận chia sẻ
loading
Không tìm thấy câu trả lời bạn tìm kiếm? Duyệt qua các câu hỏi được gắn thẻ python google-app-engine validation wtforms , hoặc hỏi câu hỏi của bạn.

Có thể bạn quan tâm

loading