【问题标题】:Reading Checkbox in Django在 Django 中读取复选框
【发布时间】:2015-06-25 03:41:16
【问题描述】:

只是另一个阅读 Django 复选框。我在这里阅读了关于 Checkbox 的 7 篇不同的帖子以及 Django 文档中的 4 个其他页面。我的情况有点不同。我无法读取是否选中了特定复选框。即使只选中一个复选框,我也只会为两个复选框获得一个值“True”。如果未检查任何内容,则它按预期工作。我真的需要使用 MultipleChoiceField 吗?

电流输出:

- John Doe Location A True   ===> Checked
 - James Smith Location A True    ===> Unchecked

理想情况下,我想要一个包含

的字典列表
data [0] = {'John', 'Doe', 1}
data [1] = {'John', 'Smith', 0}
...

其中“1”是覆盖标志,“0”是忽略。

背景:

  1. 用户提交表单
  2. 如果发现重复项,则第二种形式会在名称旁边显示带有复选框的先前信息。如果它们不重复,则不会出现复选框。
  3. 读入复选框,处理并显示最终页面。

forms.py

from django import forms
from django.forms.formsets import BaseFormSet

class NameForm (forms.Form):

    first_name = forms.CharField (max_length = 20, required = False)
    last_name = forms.CharField (max_length = 20, required = False)

class BaseNameFormSet (BaseFormSet):
...

class CheckBox (forms.Form):
    overwrite = forms.BooleanField (required = False)

views.py

def addname (request):
....

if request.method == 'POST':
    ....

    if formset.is_valid ():
        location = request.POST ['site']
        data = formset.cleaned_data

        # Store data into session to be used in another method
        request.session ['location'] = location
        request.session ['data'] = data


def process (request):

    location = request.session ['location']
    data = request.session ['data']

    if request.method == 'POST':
        form = CheckBox (request.POST)

        if form.is_valid ():
            overwrite = form.cleaned_data.get ('overwrite')

        # for duplicate in checkboxes:
        #    overwrite = duplicate.get ('overwrite')
        print (overwrite)

        context = {'data': data, 'location': location, 'overwrite': overwrite}
        return render (request, 'nodeform/success.html', context)

    return HttpResponse ('No Overwrite Data.')

response.html

<!DOCTYPE html>
<html>
<head lang="en">
    <meta charset="UTF-8">
    {% load staticfiles %}
    <link rel="stylesheet" type="text/css" href="{% static 'nameform/style.css' %}" >
    <title>Submitted Entries</title>
</head>
<body>
    <h1>Submitted Entries:</h1>
    <h4>Location: {{ location }}</h4>
    <form action="process" method="POST">{% csrf_token %}
    <div id="tablefont">
    <table id="table01">
        <tr>
            <th>First Name</th>
            <th>Last Name</th>
            <th class="center">Overwrite</th>
        </tr>
        {% for info in data %}
        <tr>
            <td>{{ info.first_name }}</td>
            <td>{{ info.last_name }}</td>
            <td class="center"><input type="checkbox" name='overwrite-{{ forloop.counter0 }}'></td>  ===> Testing Checkbox
                <!--
                {% if info.overwrite %}
                <td class="center"><input type="checkbox" name='overwrite-{{ forloop.counter0 }}'></td>
                {% else %}
                <td class="center"></td>
                {% endif %}
                -->
        </tr>
        {% endfor %}
    </table>
    </div>
    <br>
    {% if errors %}
    <p class="errorlh">Error:
        <ul>
        {% for error in errors %}
            <li>{{ error }}</li>
        {% endfor %}
        </ul>
    </p>
    {% endif %}
    <br>
    <p><input type="submit" value="Confirm">
    <a href="{% url 'addname' %}">
        <button type="button">Cancel</button></a></p>
    </form>
</body>
</html>

成功.html

<!DOCTYPE html>
<html>
<head lang="en">
    <meta charset="UTF-8">
    <title>Successfully Added</title>
</head>
<body>
    <h1>Information captured:</h1>
    <ul>
    {% for info in data %}
        <li>{{ info.first_name }} {{ info.last_name }} {{ location }} {{ overwrite }}</li>
    {% endfor %}
    </ul>
    <a href="{% url 'addname' %}">Add more names</a>
</body>
</html>

【问题讨论】:

  • 问题的核心是您似乎使用了多个具有相同名称和相同值的复选框。当您提交 HTML 表单时,活动复选框会报告为 name=value - 因此您可以使用复选框来收集共享名称的多个值,但拥有多个共享两个设置的复选框是没有意义的。典型的 Django 解决方案是定义一个表单,其中包含您要为每一行跟踪的所有字段(如名字、姓氏、位置和覆盖),然后使用它来构建一个表单集。
  • 尝试为每个复选框指定不同的名称
  • 您听说过表单集吗?也许它会满足你的要求docs.djangoproject.com/en/1.8/topics/forms/formsets
  • 感谢您指出这一点。让我尝试一下 Ella 指出的简单路线。除非您有更好的建议,否则我正在考虑索引“名称”。是的,我知道表单集。事实上,直到复选框部分为止,整个表单都是建立在表单集上的。
  • @Peter - 我的第一页只收集名字和姓氏。一旦处理完毕,它将显示带有覆盖复选框的第二页。这是否意味着我必须收集两次数据?

标签: python django checkbox django-forms


【解决方案1】:

您所有的复选框输入都具有相同的属性name=overwrite,因此,当您选中一个时,它将是在 POST overwrite=true 中提交的唯一一个。

您应该为每个输入指定一个唯一的名称。我建议你使用{{ forloop.counter0 }},它将提供循环的当前迭代,从0开始。基本上它是“数据”中当前“信息”的索引。

{% for info in data %}
    <tr>
        <td>{{ info.first_name }}</td>
        <td>{{ info.last_name }}</td>
        <td class="center"><input type="checkbox" name='overwrite-{{ forloop.counter0 }}'></td>  ===> Testing Checkbox
            <!--
            {% if info.overwrite %}
            <td class="center"><input type="checkbox" name='overwrite' value="1"></td>
            {% else %}
            <td class="center"></td>
            {% endif %}
            -->
    </tr>
{% endfor %}

这样,您可以将 POST 中的表单字段与后端的“信息”匹配。

【讨论】:

  • 您可以使用 Django 表单对象而不是自己编写复选框输入来获得类似的结果。
  • 如果这行得通,那么没有额外的表单集头痛会很棒。我按照你的建议做了,但结果还是一样。我的视图应该收集所有“POST”数据并将其分配给覆盖,但它没有。
猜你喜欢
  • 1970-01-01
  • 2016-05-13
  • 2011-05-27
  • 1970-01-01
  • 2013-06-29
  • 1970-01-01
  • 2011-06-01
  • 2015-07-25
相关资源
最近更新 更多