0

저는 model_form을 사용하여 App Engine 모델에서 자동으로 양식을 만듭니다. 그것은 잘 작동하지만, 만든 된 양식 ListProperty() 필드를 포함하지 않습니다. 코드 스 니펫 :ListProperty (db.Key)가있는 필드가 wtforms.ext.appengine.db를 사용하여 만든 양식에서 건너 뜁니다. import model_form?

models.py에서 :

class Team(db.Model): 

    name = db.StringProperty() 
    members = db.ListProperty(db.Key) 

views.py에서 :

def test_app(): 

    form = model_form(Team) 
    app.logger.debug("form :" + str(dir(form))) 
    return render_template("some_template.html") 

디렉토리 (형태)는 ListProperty입니다 필드 '회원'표시되지 않습니다(). 폼에 '멤버'속성이 없기 때문에 템플릿에서 'form.members'를 사용할 수 없습니다.

http://wtforms.simplecodes.com/docs/1.0.3/ext.html에는 ListProperty에 해당하는 'Field'가 없습니다. 이러한 종류의 모델을 처리하는 방법은 무엇입니까?

답변

1

WTforms는 App Engine의 ListProerty에 해당하는 'Field'를 제공하지 않으며 model_form은 '회원'입력란을 건너 뜁니다. 그래서, 우리는 '구성원'데이터 스토어 필드에 'db.Key'인스턴스를 저장하는 방법이 있습니다. 이 문제에 많은 시간을 보낸 후 마침내 회원 필드에 'db.Key'인스턴스를 저장할 수있었습니다. 다음 코드 조각은 다음과 같습니다

models.py : 가능한 모든 구성원의

class Team(db.Model): 
    members = db.ListProperty(db.Key) 

이후 멤버 저장 'db.Key'인스턴스입니다. 표시된 양식에는 여러 선택 필드가있어 사용자가 여러 멤버를 선택할 수 있습니다. WTforms를 사용했습니다.

forms.py :

class TeamForm(wtf.Form): 
    members = wtf.SelectMultipleField('Members', validators=[validators.Required()]) 

views.py :

class create_team(): 
    form = TeamForm() 
    form.members.choices = [(u.key(), u.name) for u in Member.all().order('name')] 
    return render_template("create_team.html", form=form) 

HTML 그냥 당신이 "오류가 발생 할 양식을 저장하려고하면 fields.Now을 형성 렌더링 'sdjfsjdfks23746jhew874가'있다 이 필드에 대해 유효한 선택이 아닙니다. " 나는 wtforms/fields/core.py를 열어 WTforms 코드를 파고 들었다.

class SelectMultipleField(SelectField): 
    """ 
    No different from a normal select field, except this one can take (and 
    validate) multiple choices. You'll need to specify the HTML `rows` 
    attribute to the select field when rendering. 
    """ 
    widget = widgets.Select(multiple=True) 

    def iter_choices(self): 
     for value, label in self.choices: 
      selected = self.data is not None and self.coerce(value) in self.data 
      yield (value, label, selected) 

    def process_data(self, value): 
     try: 
      self.data = list(self.coerce(v) for v in value) 
     except (ValueError, TypeError): 
      self.data = None 

    def process_formdata(self, valuelist): 
     try: 
      self.data = list(self.coerce(x) for x in valuelist) 
     except ValueError: 
      raise ValueError(self.gettext('Invalid choice(s): one or more data inputs could not be coerced')) 

    def pre_validate(self, form): 

     if self.data: 
      values = list(c[0] for c in self.choices) 
      for d in self.data: 
       if d not in values: 
        raise ValueError(self.gettext("'%(value)s' is not a valid choice for this field") % dict(value=d)) 

사전 확인 기능에서 오류가 발생했습니다. self.choices에는 views.py에서 제공 한 모든 선택 사항이 들어 있으며 여기에는 [(db.Key 인스턴스, 멤버 이름), ...]이 포함됩니다. db.Key 인스턴스는 html 형식으로 보내지지만 유니 코드 형태로 전송됩니다. 따라서 self.data에는 db.Key 인스턴스 각각에 대한 유니 코드 값 목록이 들어 있습니다. 그 이유는

if d not in values: 

이 조건을 만족하므로 예외가 발생합니다. 그것은 다음과 같이 내가 사전 검증() 함수를 변경 작업을하려면 views.py 연료 소모량의 데이터 저장소에서 양식 날짜를 저장하는 동안,

def pre_validate(self, form): 

    if self.data: 
     values = list(unicode(c[0]) for c in self.choices) 
     for d in self.data: 
      if d not in values: 
       raise ValueError(self.gettext("'%(value)s' is not a valid choice for this field") % dict(value=d)) 

이제 (나는 다른에 무엇을 모른다). 이것을 사용하십시오 :

members = [db.get(data).key() for data in form.members.data if data] 

유니 코드를 'db.Key'인스턴스로 변환하십시오. 누군가가 도움이되기를 바랍니다. 더 좋은 방법이 있으면 알려주세요.