我想用Django 1.3(使用Python 2.7)测试Google Maps Static API。为此,我创建了一个简单的表格来查询坐标(纬度和经度),缩放级别和地图大小。表格如下:
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 :(得分:3)
您遇到的根本问题是因为您决定通过直接HTML输出表单字段,以便添加placeholder
属性,这样做就错过了最重要的一点 - { {1}}属性。另外,如果表单验证失败,他们将不会重新显示现有值。
您应该将占位符添加到表单字段本身,而不是这样做:
name
并依靠Django输出它们:
latitude = forms.FloatField(required=True, min_value=-90.0, max_value=90.0,
widget=forms.TextInput(attrs={'placeholder': 'latitude'}))
答案 1 :(得分:2)
表单似乎是空的,因为输入标记不包含任何名称或值属性:
<input type="text" class="input-small" placeholder="{{ field.html_name }}">
要让浏览器发送任何数据,输入标记应具有名称属性:
<input type="text" class="input-small" placeholder="{{ field.html_name }}" name="{{ field.html_name }}">
对于显示任何值的输入,输入应具有值属性。要获取您要执行form.data['field_name']
字段的值,但我们无法在模板中执行此操作。所以我们创建一个模板过滤器。如果您不知道如何操作,请参阅the documentation 。这是一个快速的方法:
在您的应用中创建templatetags subdir
在该目录中创建一个空的__init__.py
在该目录中创建文件“yourapp_tags.py”
以下是您可以在该脚本中添加的代码示例:
from django import template
register = template.Library()
@register.filter
def get_field_value(field):
return field.form.data.get(field.name, '')
然后您可以在模板中使用它来设置初始字段值:
<input type="text" class="input-small" placeholder="{{ field.html_name }}" name="{{ field.html_name }}" value="{{ field|get_field_value }}">
不要忘记模板中的{% load yourapp_tags %}
或get_field_value将无法识别!
答案 2 :(得分:0)
我知道这个问题已经得到解答了,但是由于这个问题涉及在模板中迭代graular表单输出,我想我之前分享了我之前的格式,我没有遇到任何问题
<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&amp; HTML布局。我开始使用它来更好地适应我购买的模板的样式。