2017-05-29 133 views
1

我是新奇的蟒蛇世界,我想用谷歌蘋果引擎的外部API,我想讓一個窗體驗證與填充Api的JSON響應的selectField。蟒蛇 - 燒瓶驗證SelectField

這是我的代碼

class CommentForm(FlaskForm): 
    name = StringField('Nome', [required()]) 
    nazionalita = SelectField('Nazionalita',[required()]) 
    eta = IntegerField('Eta', [required()]) 
    Comment = TextAreaField('Commento', [required()]) 
    Data = DateTimeField('Data',[required()],format='%d/%m/%Y',) 
    submit = SubmitField('Inserisci', [required()]) 

    def validate_nazionalita(form): 
     if not form.nazionalita.data == None: 
      raise ValidationError('Nazionalita non selezionata') 

@app.route('/insert', methods=['GET']) 
def insert(): 
    form = CommentForm() 
    url = 'https://ajayakv-rest-countries-v1.p.mashape.com/rest/v1/all' 
    req = urllib2.Request(url) 
    req.add_header('X-Mashape-Key', MASHAPE_KEY) 
    req.add_header('Accept', 'application/json') 
    urlresponse = urllib2.urlopen(req) 
    content = urlresponse.read() 

    responde = make_response(content) 

    responde.headers['content-type']='application/json' 
    data = json.loads(responde.data) 
    nation = list(data) 
    scelte =[] 
    scelte = ([(s['callingCodes'] , s['name'])for s in nation]) 
    form.nazionalita.choices= scelte 
    return render_template('insert.html', form=form) 


@app.route('/insert', methods=['POST']) 
def submit(): 
    form = CommentForm(request.form) 
    if not form.validation(): 
     return render_template('insert.html', form=form), 400 
    return redirect('/') 

,這是html頁面:

<form method="post" action="/insert"> 
     {{ form.csrf_token }} 
     <div> {{form.name.label}}: {{form.name}} </div> 

     {% if form.name.errors %} 
      <ul class=errors> 
       {% for error in form.name.errors %} 
        <li>{{ error }}</li> 
       {% endfor %} 
      </ul> 
     {% endif %} 


     <div> {{form.nazionalita.label}}: {{form.nazionalita}} </div> 

     {% if form.nazionalita.errors %} 
      <ul class=errors> 
       {% for error in form.nazionalita.errors %} 
        <li>{{ error }}</li> 
       {% endfor %} 
      </ul> 
     {% endif %} 

     <div> {{form.eta.label}}: {{form.eta}} </div> 

     {% if form.eta.errors %} 
      <ul class=errors> 
       {% for error in form.eta.errors %} 
        <li>{{ error }}</li> 
       {% endfor %} 
      </ul> 
     {% endif %} 

     <div> {{form.Data.label}}: {{form.Data}} </div> 

     {% if form.Data.errors %} 
      <ul class=errors> 
       {% for error in form.Data.errors %} 
        <li>{{ error }}</li> 
       {% endfor %} 
      </ul> 
     {% endif %} 

     <div> {{form.Comment.label}}: {{form.Comment}} </div> 

     {% if form.Comment.errors %} 
      <ul class=errors> 
       {% for error in form.Comment.errors %} 
        <li>{{ error }}</li> 
       {% endfor %} 
      </ul> 
     {% endif %} 

     <div> {{form.submit}} </div> 
    </form> 

如果我刪除selectField所有工作得很好,但它的錯誤是:

`Traceback (most recent call last): 
    File "/home/roberto/Scrivania/google-cloud-sdk/platform/google_appengine/google/appengine/runtime/wsgi.py", line 267, in Handle 
    result = handler(dict(self._environ), self._StartResponse) 
    File "/home/roberto/Scrivania/simulazione/lib/flask/app.py", line 1994, in __call__ 
    return self.wsgi_app(environ, start_response) 
    File "/home/roberto/Scrivania/simulazione/lib/flask/app.py", line 1985, in wsgi_app 
    response = self.handle_exception(e) 
    File "/home/roberto/Scrivania/simulazione/lib/flask/app.py", line 1540, in handle_exception 
    reraise(exc_type, exc_value, tb) 
    File "/home/roberto/Scrivania/simulazione/lib/flask/app.py", line 1982, in wsgi_app 
    response = self.full_dispatch_request() 
    File "/home/roberto/Scrivania/simulazione/lib/flask/app.py", line 1614, in full_dispatch_request 
    rv = self.handle_user_exception(e) 
    File "/home/roberto/Scrivania/simulazione/lib/flask/app.py", line 1517, in handle_user_exception 
    reraise(exc_type, exc_value, tb) 
    File "/home/roberto/Scrivania/simulazione/lib/flask/app.py", line 1612, in full_dispatch_request 
    rv = self.dispatch_request() 
    File "/home/roberto/Scrivania/simulazione/lib/flask/app.py", line 1598, in dispatch_request 
    return self.view_functions[rule.endpoint](**req.view_args) 
    File "/home/roberto/Scrivania/simulazione/app/handlers/insert.py", line 46, in submit 
    if not form.validate(): 
    File "/home/roberto/Scrivania/simulazione/lib/wtforms/form.py", line 310, in validate 
    return super(Form, self).validate(extra) 
    File "/home/roberto/Scrivania/simulazione/lib/wtforms/form.py", line 152, in validate 
    if not field.validate(self, extra): 
    File "/home/roberto/Scrivania/simulazione/lib/wtforms/fields/core.py", line 193, in validate 
    self.pre_validate(form) 
    File "/home/roberto/Scrivania/simulazione/lib/wtforms/fields/core.py", line 468, in pre_validate 
    for v, _ in self.choices: 
    TypeError: 'NoneType' object is not iterable` 

,我不明白爲什麼如何解決這個問題。
謝謝大家。

+1

Hello Roberto,歡迎來到Stackoverflow。爲了確保獲得快速且有用的響應,請參閱指南[如何創建最小,完整和可驗證示例](https://stackoverflow.com/help/mcve),並嘗試縮小代碼以描述您的代碼問題沒有太多的開銷。 – MrLeeh

+0

謝謝你mrleeh,我會採納你的建議 –

+0

你能打印你的'scelte'嗎? –

回答

1

我終於能夠重現你的錯誤:你正在爲GET方法的視圖函數中創建選擇。但是您並未將它們添加到POST方法的視圖函數中。通過稍微修改您的submit()功能解決這個問題:

@app.route('/insert', methods=['POST']) 
def submit(): 
    form = CommentForm(request.form) 
    scelte = [(s['callingCodes'] , s['name'])for s in nation] 
    form.nazionalita.choices= scelte 

    if not form.validate(): 
     return render_template('insert.html', form=form), 400 
    return redirect('/') 

這樣你還可以添加的選項在您的文章功能,可以驗證他們。一個更清潔的方法是放置GET和相同功能的POST處理程序:

注:在你的原始版本form.validate()函數試圖找出如果你通過了form.nazionalita.choices列表迭代做出有效的選擇。因爲你沒有在Form類中設置任何選項,所以它是None。並試圖迭代None引發你得到的異常。

+0

謝謝你的時間@Mrleeh你的意思是,我作爲全球變種的國家嗎?順便說一下,我的表單似乎沒有驗證()「AttributeError:'CommentForm'對象沒有屬性'驗證'」 –

+0

看看http://flask-wtf.readthedocs.io/en/stable/quickstart.html#驗證表單。嘗試修改你的代碼來匹配這種模式,你應該很好。 – MrLeeh