2017-04-07 1 views
1
class Example_Form(Form): 
    field_1 = TextAreaField() 
    field_2 = TextAreaField() 

    def __init__(self, type, **kwargs): 
     super(Example_Form, self).__init__(**kwargs) 

     if type == 'type_1': 
      self.field_3 = TextAreaField() 

일부 시나리오에서는 양식에 필드를 동적으로 추가해야합니다. 예제 양식에 추가 된 field_3은 UnboundField로 밝혀졌습니다. 필드 _3을 __init__ 함수로 묶으려고했으나 작동하지 않습니다.양식의 __init__ 함수에서 필드를 바인딩하는 방법

field_3 = TextAreaField() 
field_3.bind(self, 'field_3') 

field_3을 예제 폼에 바인딩하는 방법은 무엇입니까?

+1

이 특정 사례에 대해 'Example_Form'의 하위 클래스를 원하십니까? 필드는 인스턴스 속성이 아닌 클래스 선언이며, 그 차이는 설명자 프로토콜 및 다른 메타 프로그래밍 기술에서 중요합니다. 'WTForms'이 사용하기 쉽습니다. – ShadowRanger

답변

1

self.meta.bind_field을 사용하여 바운드 필드를 만들고이를 인스턴스에 할당하고 _fields dict에 할당합니다. 대부분의 경우


self.field_3 = self._fields['field_3'] = self.meta.bind_field(
    self, TextAreaField(), 
    {'name': 'field_3', 'prefix': self._prefix} 
) 

, 그것은 서브 클래스를 사용하여 양식 인스턴스를 생성 할 때 사용할 클래스를 결정하는 것이 더 분명하다.

class F1(Form): 
    x = StringField() 

class F2(F1): 
    y = StringField() 

form = F1() if type == 1 else F2() 

더욱 역동적이어야하는 경우 양식을 서브 클래스 화하고 필드를 할당 할 수 있습니다. 클래스와 필드를 할당하면 인스턴스와 달리 직접 작동합니다.

class F3(F1): 
    pass 

if type == 3: 
    F3.z = StringField() 

form = F3() 

또한 모든 필드를 정의한 다음 양식을 검증하기 전에 일부 필드를 삭제할 수도 있습니다.

+0

고맙습니다. 'self.meta.bind_field'가 작동합니다! 필드를 추가 할 수 있습니다. 필드를 출력하려 할 때, AttributeError가 반환되었습니다. 'SelectField'객체에는 'data'속성이 없습니다. – LeonF

+0

필드 자체에 필드를 추가 할 수 없으며 클래스 만 추가 할 수 있으므로'self [ 'field_3']'을 제거해야합니다. – LeonF

+0

필드 객체의'process_data' 함수가 자동으로 호출되지 않습니다. – LeonF

관련 문제