2014-10-07 20 views
6

Có cách nào để loại bỏ khoảng trắng xung quanh khỏi tất cả các giá trị trong WTForms mà không thêm bộ lọc vào mọi trường không?Tự động ngắt() tất cả các giá trị trong WTForms?

Hiện tại tôi đang chuyển filters=[strip_whitespace] với chức năng được hiển thị bên dưới vào các trường của tôi nhưng phải lặp lại điều này cho mọi trường là khá xấu.

def strip_whitespace(s): 
    if isinstance(s, basestring): 
     s = s.strip() 
    return s 

Một giải pháp yêu cầu phân lớp Form sẽ không sao vì tôi đã làm điều đó trong đơn đăng ký của mình.

Trả lời

8

Bạn có thể làm điều đó trong WTForms 2.x bằng bind_field nguyên thủy trên class Meta. Mô hình class Meta là một cách để ghi đè các hành vi của WTForms trong các ngữ cảnh như các trường ràng buộc/khởi tạo, các trường hiển thị và hơn thế nữa.

Bởi vì bất cứ điều gì ghi đè trong class Meta xác định trên một mẫu được thừa hưởng bất kỳ lớp con hình thức, bạn có thể sử dụng nó để thiết lập một lớp hình thức cơ bản với hành vi mong muốn của bạn:

class MyBaseForm(Form): 
    class Meta: 
     def bind_field(self, form, unbound_field, options): 
      filters = unbound_field.kwargs.get('filters', []) 
      filters.append(my_strip_filter) 
      return unbound_field.bind(form=form, filters=filters, **options) 


def my_strip_filter(value): 
    if value is not None and hasattr(value, 'strip'): 
     return value.strip() 
    return value 

Bây giờ, chỉ cần kế thừa MyBaseForm cho tất cả hình thức của bạn và bạn tốt để đi.

+0

Tôi nghĩ rằng nó phải là 'get' thay vì' pop' hoặc bất kỳ, nhưng Form đầu tiên sẽ không có bất kỳ bộ lọc tùy chỉnh. Ngoài ra, dòng đó có thể được đơn giản hóa một chút: 'filters = unbound_field.kwargs.get ('filters', [])' – ThiefMaster

+0

@ThiefMaster cảm ơn, sẽ sửa mã ví dụ – Crast

+0

Điều này không thể thực hiện trên 'FormField' như FormField không thể lấy bộ lọc , vì vậy hãy kiểm tra trước khi 'không issubclass (unbound_field.field_class, FormField)' – gdoumenc

1

Tôi sẽ không ngạc nhiên nếu bạn có thể làm điều đó bằng cách phân loại biểu mẫu, nhưng giải pháp của tôi là chỉ tạo các trường tùy chỉnh * bị tước. Tôi nghĩ rằng đây là ít nhất là tốt hơn so với đi qua bộ lọc mỗi lần vì nó ít dễ bị lỗi:

from wtforms import StringField, PasswordField 


class Stripped(object): 
    def process_formdata(self, valuelist): 
     if valuelist: 
      self.data = valuelist[0].strip() 
     else: 
      self.data = '' 

class StrippedStringField(Stripped, StringField): pass 
class StrippedPasswordField(Stripped, PasswordField): pass 
+0

Không thực sự là một giải pháp tốt vì nó đòi hỏi subclassing mỗi lĩnh vực duy nhất (WTForms có rất nhiều người trong số họ) – ThiefMaster

0

Thật không may, tôi không có đủ danh tiếng để nhận xét phản hồi đầu tiên. Nhưng, có lỗi cực kỳ khó chịu trong ví dụ đó: Khi bạn thực hiện filters.append (smth) thì trên mỗi bộ lọc khởi tạo biểu mẫu theo 1 phần tử. Kết quả là, mã của bạn hoạt động chậm hơn và chậm hơn cho đến khi bạn khởi động lại nó

xem xét Ví dụ:

class MyBaseForm(Form): 
     class Meta: 
      def bind_field(self, form, unbound_field, options): 
       filters = unbound_field.kwargs.get('filters', []) 
       filters.append(my_strip_filter) 
       return unbound_field.bind(form=form, filters=filters, **options) 


    def my_strip_filter(value): 
     if value is not None and hasattr(value, 'strip'): 
      return value.strip() 
     return value 

    class MyCustomForm(MyBaseForm): 
     some_field = StringField(filters=[lambda x: x]) 

    for i in range(100): 
     MyCustomForm(MultiDict({'some_field': 'erer'})) 

    print(len(MyCustomForm.some_field.kwargs['filters'])) # print: 101 

Vì vậy, việc sửa chữa nhanh chóng là để kiểm tra xem bộ lọc này không có trong danh sách:

class MyBaseForm(Form): 
    class Meta: 
     def bind_field(self, form, unbound_field, options): 
      filters = unbound_field.kwargs.get('filters', []) 
      if my_strip_filter not in filters: 
       filters.append(my_strip_filter) 
     return unbound_field.bind(form=form, filters=filters, **options) 
Các vấn đề liên quan