2012-03-02 8 views
1

Google Maps Static APIをDjango 1.3(Python 2.7を使用)でテストしたいと思います。この目的のために、座標(緯度&経度)、ズームレベル、およびマップサイズを照会するための簡単なフォームを作成しました。フォームは次のようになります。それぞれのビューでDjangoフォームはコンソールで検証されますが、なぜブラウザにはありませんか?

from django import forms 

class GoogleMapsStaticApiForm(forms.Form): 
    latitude = forms.FloatField(required=True, min_value=-90.0, max_value=90.0) 
    longitude = forms.FloatField(required=True, min_value=-180.0,max_value=180.0) 
    zoom_level = forms.IntegerField(required=True, min_value=0, max_value=21) 
    map_width = forms.IntegerField(required=True, min_value=0, max_value=640) 
    map_height = forms.IntegerField(required=True, min_value=0, max_value=640) 

、私は形で与えられた情報からURLを構築し、同じテンプレートにマップをレンダリングする必要がありますテンプレートにURLを返すようにしたいです。

ビュー:

def map_properties(request): 
    map_url = 'http://maps.google.com/maps/api/staticmap?' 

    if request.method == 'POST': 
     form = GoogleMapsStaticApiForm(request.POST) 
     if form.is_valid(): 
      center = 'center={0},{1}'.format(form.latitude, form.longitude) 
      zoom = 'zoom={0}'.format(form.zoom_level) 
      size = 'size={0}x{1}'.format(form.map_width, form.map_height) 
      url_suffix = '&'.join((center, zoom, size, 'sensor=false')) 
      map_url = ''.join((map_url, url_suffix)) 
    else: 
     form = GoogleMapsStaticApiForm() 

    return render_to_response('frontend/frontend.html', 
          {'form':form, 'map_url':map_url}, 
          context_instance=RequestContext(request)) 

テンプレート:

<html> 
    <head> 
     <title>Google Maps Static API - Demo</title> 
    </head> 
    <body> 

     <form method="post" accept-charset="UTF-8"> 
      {% csrf_token %} 

      {% for field in form %} 
       <input type="text" placeholder={{ field.html_name }}> 
      {% endfor %} 
      <button type="submit">Show the fancy map!</button> 
     </form> 

     {% if form.is_valid %} 
      <p><img src="{{ map_url }}" alt="Google Maps Static Map"></p> 
     {% else %} 
      <p>Form is not valid</p> 
     {% endif %} 

    </body> 
</html> 

私はDjangoのコンソールの例のデータでフォームを検証しようとすると、それが正常に動作します:

>>> from frontend.forms import GoogleMapsStaticApiForm 
>>> data = {'latitude':51.477222, 'longitude':0.0, 'zoom_level':12, 'map_width':400, 'map_height':400} 
>>> f = GoogleMapsStaticApiForm(data) 
>>> f.is_valid() 
True 

しかし、ブラウザに同じデータを入力して[送信]ボタンを押すと、同じテンプレートがリロードされますが、生成されたマップフォームは決して検証されないようです。誰が私にこの事件の理由を教えてもらえますか?どうもありがとうございました!

+0

「フォームが無効です」と表示されるのではなく、「フォーム。エラー」を表示しないのはなぜですか?そして、それがなぜ有効でないのか分かります。 –

+0

Daniel、私はそれを試みましたが、{{form.errors}}は常にすべてのフィールドが必要であることを示しています。フォームを送信すると、フィールドが必要なメッセージと同じメッセージが、まったく同じページに再ロードされます。 – pemistahl

+0

さて、 'jpic'によると、各HTMLフィールドには' name'属性が必要です。 –

答えて

2

フォームがinputタグには任意の名前や値属性含まれていないため、空であるように見えます:任意のデータを送信するために、ブラウザのために

<input type="text" class="input-small" placeholder="{{ field.html_name }}"> 

を、入力タグは、name属性を持つ必要があります:任意の値を表示するための入力用

<input type="text" class="input-small" placeholder="{{ field.html_name }}" name="{{ field.html_name }}"> 

入力はvalue属性を持っている必要があります。フィールドの値を取得するには、form.data['field_name']を実行しますが、テンプレートではそれを行うことはできません。そこで、テンプレートフィルタを作成します。方法がわからない場合はthe documentationを参照してください。ここでは簡単HOWTOだ:

  1. templatetagsを作成し、あなたのアプリでをSUBDIR

  2. を "yourapp_tags.py" のファイルを作成し、そのディレクトリ内の空__init__.py

  3. を作成します。そのディレクトリにある

することを忘れないでください

<input type="text" class="input-small" placeholder="{{ field.html_name }}" name="{{ field.html_name }}" value="{{ field|get_field_value }}"> 

from django import template 

register = template.Library() 

@register.filter 
def get_field_value(field): 
    return field.form.data.get(field.name, '') 

は、その後、あなたが最初のフィールドの値を設定するためのテンプレートでそれを使用することができます:0

は、ここでは、そのスクリプトに入れることができ、コードの例ですテンプレート内の{% load yourapp_tags %}またはget_field_valueは認識されません。

+0

ありがとう、jpic。私はまだこれがなぜ機能するのか完全に理解していませんが、今はうまくいきます。私はこの文書をすべて読み上げます。 これまでのところ、私はDjangoで1つのプロジェクトしか行っていません。これは、name属性が決して必要とされなかったModelFormsのみを使用していました。 Modelformはちょうどいくつかのデータをデータベースに保存して、完全に別のページにリダイレクトしました。このフォーム構造を現在のプロジェクトに適用しようとしましたが、明らかにうまくいかなかったのです。とにかく、私は新しいものを学んでいます。それは素晴らしいことです。 :-) – pemistahl

+0

ダニエルの答えも読んで理解する必要があります! – jpic

3

placeholder属性を追加するためにフォームフィールドを直接HTML経由で出力することを決定し、最も重要なビット - つまりname属性を逃してしまったため、根底にある問題があります。さらに、フォームが検証に失敗した場合、既存の値を再表示しません。

latitude = forms.FloatField(required=True, min_value=-90.0, max_value=90.0, 
         widget=forms.TextInput(attrs={'placeholder': 'latitude'})) 

と出力それらにジャンゴに依存している:

これを行うのではなく、あなたがフォームにプレースホルダを追加する必要が自分自身をフィールド

{% for field in form %} 
    {{ field }} 
{% endfor %} 
+0

あなたの助言に感謝、ダニエル。私はこれを試してみる。 – pemistahl

0

私が知っている、この質問が既に回答されていますしかし、この問題はテンプレートの砂糖フォームの出力を繰り返すことに関連しているので、私は以前にどのようにフォーマットしたのか分かりましたが、何の問題もありませんでした。

<form class="form label-inline" action="" method="post">{% csrf_token %} 

    {{ form.non_field_errors }} 

    {% for field in form.visible_fields %} 
     <div class="field"> 
      {{ field.errors }} 
      <label for="{{ field.auto_id }}">{{ field.label }}</label> 
      {{ field }} 
      {% if field.help_text %} 
      <p class="field_help">{{ field.help_text }}</p> 
      {% endif %} 
     </div> <!-- end div.field --> 
    {% endfor %} 

    {% for hidden in form.hidden_fields %} 
     {{ hidden }} 
    {% endfor %} 

    <input type="submit" value="Save" name="submit" /> 
</form> 

それはエラー、隠された入力、およびhelp_textにをカバーし、それがCSS & HTMLレイアウトをカスタマイズするための本当に便利です。私は購入したテンプレートのスタイリングに合わせてこれを使い始めました。

関連する問題