【问题标题】:(still unAnswered) django checkbox save yes or no in the database(仍然未回答)django 复选框在数据库中保存是或否
【发布时间】:2020-03-08 19:25:26
【问题描述】:
  <form id="form" name="form">
    <input type="checkbox" value="1" name="Asthma" data-form-field="Option" class="form-check-input display-7" id="checkbox1"  title="Check if Student have Asthma">
    <input type="checkbox" value="1" name="Congenital" data-form-field="Option" class="form-check-input display-7" id="checkbox1" title="Check if Student have Congenital Anomalies">
    <input type="checkbox" value="1" name="Contact" data-form-field="Option" class="form-check-input display-7" id="checkbox1" title="Check if Student use Contact lens">
  </form>

我的 html 中有这段代码

<script type="text/javascript">
                        // when page is ready
                        $(document).ready(function() {
                             // on form submit
                            $("#form").on('submit', function() {
                                // to each unchecked checkbox
                                $(this + 'input[type=checkbox]:not(:checked)').each(function () {
                                    // set value 0 and check it
                                    $(this).attr('checked', true).val(0);
                                });
                            })
                        })
                    </script>

我的问题是每次我将结果保存到我的数据库中时,结果总是自动是,即使我未选中 html 中的复选框(否)。 我不知道我的 javascript 是否正确

这是我的观点.py

    Asthma = request.POST['Asthma']
    Congenital = request.POST['Congenital']
    Contact = request.POST['Contact']
V_insert_data = StudentUserMedicalRecord( 
        Asthma=Asthma,
        CongenitalAnomalies=Congenital,
        ContactLenses=Contact
   )
 V_insert_data.save()

models.py

Asthma=models.BooleanField(null=True, blank=True, default=False)
CongenitalAnomalies=models.BooleanField(null=True,blank=True, default=False)
ContactLenses=models.BooleanField(null=True,blank=True, default=False)

html.py

即使我从我的 html 插入记录也未选中(否),结果总是在我的数据库中自动“是”,你能修复我的 javascript 代码吗?好像不行。

【问题讨论】:

  • 你能澄清你的问题吗?你想做什么?
  • 我的意思是每次我保存到我的数据库中,即使我没有选中 html 中的复选框,结果也总是被选中
  • 那是你的代码还是别人的? cmets 给你一个线索:这里有一个循环检查所有复选框:$(this).attr('checked', true).val(0);
  • 我从网上复制了这段 javascript 代码,但我看不懂,我的 javascript 不太好
  • 我给你发了答案。

标签: javascript django


【解决方案1】:

引用自此来源的文字:https://docs.joomla.org/Talk:Checkbox_form_field_type

同样的问题不仅适用于 Joomla 项目,也适用于使用复选框的其他网络应用或网站(特别注意粗体部分)。

需要特别注意保存未选中的复选框 表单!!这是组件开发人员思考的常见错误 Joomla 会处理这个问题。 Joomla 没有,直到现在。 (问题在 Joomla 2.5 仍然。)

你看,在保存带有未选中复选框的表单时,有 在 POST 数据中没有变量! 所以,很常见的是 值不会在您的数据库中被覆盖,特别是如果它已经 在表单上表示“已检查”的值(例如 1 )上。

这就是您问题中的 JavaScript sn-p 的用途。

// when page is ready
$(document).ready(function() {
  // on form submit
  $("#form").on('submit', function() {
    // to each unchecked checkbox
    $('input[type=checkbox]:not(:checked)').each(function() {
      // set value 0 and check it
      $(this).attr('checked', true).val(0);
    })
  })
})

我删除了 $(this + 部分,因为这会破坏事情。

澄清:脚本检查未选中的复选框(以确保有一个复选框被张贴)。但同时它将checked状态下的值更改为0(!)

因此,如果您有未选中的框,它们将代表 0,而不是被排除在 POST 请求数据之外。而且,当您自己检查了项目时,它会不理会它们,它将在复选框的 POST 数据中表示为值 1。

重复的 ID 也是您需要防止的。它不是有效的 HTML5。

你也有这个代码: request.POST['Asthma']

我检查并发现它返回一个QueryDict。在此页面上发现: https://docs.djangoproject.com/en/2.2/ref/request-response/#django.http.QueryDict

该页面的示例:

QueryDict('a=1&amp;a=2&amp;c=3') 返回:&lt;QueryDict: {'a': ['1', '2'], 'c': ['3']}&gt;

这意味着例如request.POST['Asthma'] 将始终返回一个列表,该列表可能被强制转换为布尔类型。因此,无论列表中的内容是什么,它都可能始终转换为 True

所以当你读到它时说:

QueryDict.__getitem__(key)¶ 返回给定键的值。如果 key 有多个值,返回最后一个值。

所以最好在这里使用__getitem__(key) 或其别名:

QueryDict.get(key, default=None)¶ 使用相同的逻辑 getitem(),带有一个钩子,用于在键不存在时返回默认值。

当然,使用 JavaScript sn-p 是您可以使用的一种方法。但是,如果您更喜欢在 Python 代码中处理这个问题,您可以像这样使用QueryDict

Asthma = request.POST.get('Asthma', '0')

【讨论】:

  • 嗨,先生,我对如何使用“QueryDict.get”有点困惑,你能提供一个与我的问题相关的例子吗?
  • 我试过这个 ""Asthma = QueryDict.__getitem__('Asthma', '0')""
  • 然后错误提示“未定义名称'QueryDict'”我不知道如何使用该QueryDict
  • 我已经添加了示例。 JavaScript 方法是有效的,但通过 Python 代码提供默认值也是有效的。任你选。如果您仍然遇到此问题,您应该提供一个更清晰的示例,也许将该示例托管在 GitHub 或 Bitbucket 上,以便我们自己进行更好的测试。
【解决方案2】:

解决方案

删除该 Javascript 代码。你不需要它。

更多详情

对于这个问题,您并不需要真正了解 Javascript。 cmets 告诉你发生了什么,但我会尽量澄清:

    // when page is ready
    $(document).ready(function() {
          // on form submit -> This means that this code will run when the form is submitted
        $("#form").on('submit', function() {
            // to each unchecked checkbox -> This means that each checkbox not checked, will run this code below
            $(this + 'input[type=checkbox]:not(:checked)').each(function () {
                // set value 0 and check it -> This means that
                $(this).attr('checked', true).val(0);
            });
        })
    })

如果您想了解更多信息,此代码使用jQuery 与函数each(用于循环遍历元素)和attr 函数(用于修改HTML 元素的属性)。

【讨论】:

  • 似乎这个 javascript 不起作用,导致它仍然是相同的结果,还是我必须更改我的复选框 ID?和价值
  • @kaito,请再次参考我的回答。正如我所说,Javascript 不适合你。只需将其完全删除。
  • 我听从了先生的指示,结果还是一样
【解决方案3】:

删除所有 javascript。这会将所有 0 转换为 1。在 views.py

中使用它
Asthma = request.POST.get('Asthma', 0)  # 0  not '0'
Congenital = request.POST.get('Congenital', 0)  # 0  not '0'
Contact = request.POST.get('Contact', 0)  # 0  not '0'

而不是这个:

Asthma = request.POST['Asthma']
Congenital = request.POST['Congenital']
Contact = request.POST['Contact']

-------------编辑------

观看次数

Asthma = request.POST.get('Asthma', 0) == '1'
Congenital = request.POST.get('Congenital', 0) == '1'
Contact = request.POST.get('Contact', 0) == '1'
V_insert_data = StudentUserMedicalRecord(
            Asthma=Asthma,
            CongenitalAnomalies=Congenital,
            ContactLenses=Contact
)
V_insert_data.save()

模板

<input type="checkbox" value="1" name="Asthma" data-form-field="Option" class="form-check-input display-7" id="checkbox1"  title="Check if Student have Asthma">
<input type="checkbox" value="1" name="Congenital" data-form-field="Option" class="form-check-input display-7" id="checkbox2" title="Check if Student have Congenital Anomalies">
<input type="checkbox" value="1" name="Contact" data-form-field="Option" class="form-check-input display-7" id="checkbox3" title="Check if Student use Contact lens">

【讨论】:

  • 您必须传递整数 0,而不是字符串“0”。并检查值是否为 0 存储 False(或否),否则保存 True(或是)。在 python 中,除了 0 以外的任何值,即使是“0”,None 也是 True。 @kaito
  • 您能给我举个例子吗?
  • @kaito,记住,删除所有 javascript。
  • @kaito。还打印所有这些值以进行检查。
  • omg,非常感谢您,先生,我现在明白了,但是我更改了您的一些答案,但别担心,我会将您的答案标记为正确 1 :)
【解决方案4】:

您不需要 javascript。还要忘记表单中的method="POST"(默认方法是GET)。

另外,对于你的views.py,你需要使用request.POSTget方法来防止KeyError异常。

models.py

from django.db import models


class StudentUserMedicalRecord(models.Model):
    Asthma = models.BooleanField(null=True, blank=True, default=False)
    CongenitalAnomalies = models.BooleanField(null=True, blank=True, default=False)
    ContactLenses = models.BooleanField(null=True, blank=True, default=False)

views.py

from django.shortcuts import render
from .models import StudentUserMedicalRecord


def sample_view(request):
    if request.method == 'POST':
        Asthma = request.POST.get('Asthma', '0')
        Congenital = request.POST.get('Congenital', '0')
        Contact = request.POST.get('Contact', '0')
        instance = StudentUserMedicalRecord(
            Asthma=Asthma,
            CongenitalAnomalies=Congenital,
            ContactLenses=Contact
        )
        instance.save()
    return render(request, 'index.html', {})

index.html

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>Project</title>
</head>
<body>
<form id="form" name="form" method="POST"> {% csrf_token %}
  <label>Asthma</label>
  <input type="checkbox" value="1" name="Asthma" data-form-field="Option" class="form-check-input display-7" id="checkbox1"  title="Check if Student have Asthma">
  <br>
  <label>Congenital Anomalies</label>
  <input type="checkbox" value="1" name="Congenital" data-form-field="Option" class="form-check-input display-7" id="checkbox1" title="Check if Student have Congenital Anomalies">
  <br>
  <label>Contact lens</label>
  <input type="checkbox" value="1" name="Contact" data-form-field="Option" class="form-check-input display-7" id="checkbox1" title="Check if Student use Contact lens">
  <br>
  <input type="submit" value="Save">
</form>
</body>
</html>

完整项目

Download here

编辑(使用ModelForms

您可以使用 django 的 ModelForm 来防止手动制作表单时出现此类问题。

所以在这种情况下,你会:

forms.py - 在 vi​​ews.py 旁边

from django import forms
from .models import StudentUserMedicalRecord


class MedicalRecordForm(forms.ModelForm):
    class Meta:
        model = StudentUserMedicalRecord
        fields = '__all__'

views.py

from django.shortcuts import render

from sample_app.forms import MedicalRecordForm


def sample_view(request):
    if request.method == 'POST':
        form = MedicalRecordForm(request.POST)
        if form.is_valid():
            form.save()
    else:
        form = MedicalRecordForm()
    return render(request, 'index.html', {'form': form})

index.html

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>Sample Project</title>
</head>
<body>
<form id="form" name="form" method="POST"> {% csrf_token %}
  {{ form.as_p }}
  <input type="submit" value="Save">
</form>
</body>
</html>

the docs找到更多关于他们的信息。

【讨论】:

  • 我得到了同样的结果,先生
  • 您是否删除了javascript?还要检查我添加的完整项目文件。我对其进行了测试,对我来说效果很好。
  • 中间有middlewaresignal吗?另请附上您的views.py 文件的完整代码。
  • 尝试删除模板中的 value="1"。
  • 当我删除该值时,我的数据库中没有插入任何内容
猜你喜欢
  • 1970-01-01
  • 2016-05-19
  • 2012-10-19
  • 1970-01-01
  • 1970-01-01
  • 2017-06-09
  • 1970-01-01
  • 1970-01-01
  • 2018-01-10
相关资源
最近更新 更多