简体   繁体   中英

(still unAnswered) django checkbox save yes or no in the database

  <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>

i have this code in my 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>

my problem is everytime i save into my database the result always automatic YES, even i unchecked the checkbox(NO) in the html. i dont know if i am doing right in my javascript

this is my views.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 在此处输入图像描述

even i insert record from my html is unchecked(No), the result always automatic "Yes" in my database, can you please fixed my javascript code? seems like its not working.

在此处输入图像描述

Cited text taken from this source: https://docs.joomla.org/Talk:Checkbox_form_field_type

The same problem not only applies to the Joomla project but also to other web apps or websites using checkboxes (especially note the bold part).

Special care needs to be taken with saving an unchecked checkbox from a form., This is a common mistake for component developers thinking Joomla takes care of this. Joomla doesn't. until now. (Problem in Joomla 2.5 still.)

You see, on saving a form with a checkbox that is unchecked, there is no variable for it in the POST data! So, it's quite common that the value will NOT be overwritten in your DB, especially if it is already on the value that represents "checked" (eg 1 ) on the form.

That's what the JavaScript snippet in your question is for.

// 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);
    })
  })
})

I removed the $(this + part because that breaks things.

To clarify: the script checks unchecked checkboxes (to make sure there is a checkbox being posted). But at the same time it changes the value when in checked state to 0 (!)

So if you have unchecked boxes, they will represent 0's instead of being left out of POST request data. And when you have checked items yourself it leaves them alone and it will represent as a value of 1 within the POST data for the checkbox(es).

Duplicate ID's are also something you need to prevent. It's not valid HTML5.

Also you have this code: request.POST['Asthma']

I've checked and found it returns a QueryDict . Found that on this page: https://docs.djangoproject.com/en/2.2/ref/request-response/#django.http.QueryDict

Example from that page:

QueryDict('a=1&a=2&c=3') returns: <QueryDict: {'a': ['1', '2'], 'c': ['3']}>

This means that eg request.POST['Asthma'] would always return a list, which might be cast to a boolean type. So no matter what's in the list, it might cast to True always.

So when you read on it says this:

QueryDict.__getitem__(key)¶ Returns the value for the given key. If the key has more than one value, it returns the last value.

So better use __getitem__(key) or its alias here:

QueryDict.get(key, default=None)¶ Uses the same logic as getitem (), with a hook for returning a default value if the key doesn't exist.

Of course, using the JavaScript snippet is one method you can use. But if you prefer to handle this in your Python code you can just use the QueryDict like this:

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

Solution

Remove that Javascript code. You don't need it.

More details

You don't really need to understand Javascript for this problem. The comments are telling you what is happening, but I will try to clarify:

    // 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);
            });
        })
    })

If you want to learn more about it, this code is using jQuery with the function each (used to loop through elements) and the attr function (used to modify a HTML element's attribute).

Try this code dear

 def analyze(request):



        asta = request.POST.get('asthma', 'off')
        cong = request.POST.get('congenital', 'off')
        cont = request.POST.get('contact', 'off')


        if asthma == "on":
            #  DO WHAT EVER YOU WANT TO DO WITH CODE YOU CAN ALSO USE ELIF 

You don't need javascript for that. Also forget about method="POST" in your form (the default method is GET ).

In addition, for your views.py , you need to use get method of request.POST to prevent KeyError exception.

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>

Full project

Download here

Edit (use ModelForms )

You can use django's ModelForm to prevent such issues with manually making the form.

So in this case, you would have:

forms.py - beside views.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>

find more about them in the docs .

Remove all javascript. That's converting all 0s to 1. Use this in 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'

instead of this:

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

-------------Edit------------------

views

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()

Template

<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">

i have fixed your code please check.

 $(document).ready(function() { $("#submit").on('click', function() { console.clear() $('input[type=checkbox]').each(function () { console.log($(this).prop('checked')); }); }) })
 <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script> <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"> <input type="button" id="submit" name="submit" value="submit" /> </form>

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM