Django表单在控制台中验证,但为什么不在浏览器中?

时间:2012-03-02 15:49:04

标签: python django google-maps django-forms

我想用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

但是当我在浏览器中输入相同的数据并按下提交按钮时,会重新加载相同的模板但没有生成的地图。这种形式似乎永远无法验证。谁能告诉我为什么会这样呢?非常感谢你!

3 个答案:

答案 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 。这是一个快速的方法:

  1. 在您的应用中创建templatetags subdir

  2. 在该目录中创建一个空的__init__.py

  3. 在该目录中创建文件“yourapp_tags.py”

  4. 以下是您可以在该脚本中添加的代码示例:

    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布局。我开始使用它来更好地适应我购买的模板的样式。