【问题标题】:Django: Trouble with updating a BooleanField with my "ToDoChecklistTask" ModelDjango:使用我的“ToDoChecklistTask”模型更新 BooleanField 时遇到问题
【发布时间】:2015-08-11 10:07:19
【问题描述】:

我现在有一个新问题。一些原始代码来自question I previously posted,,除了我的views.py 文件包含一个名为modify_checked_value 的新函数,我的jQuery 文件这次被不同地修改以向服务器发送请求以更新保存在那里的任务。在我的 URL 文件中添加了一行,并且对用于呈现我的列表的小型 HTML 模板 sn-p 进行了轻微更改。

这是我五个小时前发现并尝试解决的问题,但仍然没有成功,因为我还是 Django 新手。我有一个“待办事项列表”,我将它保存在 Django 数据库中。我使用 CharField 将任务表示为字符串,并使用 BooleanField 来确定任务是否完成(可以选择取消选中是否有人稍后发现任务未完成)。

假设我有一些任务没有选中它们的复选框,因为它们最初在创建时没有被选中。当我单击一个并打印出数据库的 QuerySet 时,我注意到从该模型返回的布尔值是 true,因此 str() 函数输出“是”作为输出的一部分细绳。当我单击同一个复选框时,布尔字段应该设置为 false,因此 __str__ 函数应该输出“否”作为字符串的一部分。

但事实证明,在选中和取消选中之后,该任务的布尔字段仍然设置为 true,因此当我完全刷新页面并且模板呈现保存的任务时,当它到达该任务时,标签被交叉。任务的布尔字段应该是假的,因此标签不应该被跨越。

当我从浏览器中取消选中复选框时,如何更新数据库中的任务对象以将其布尔字段设置为 false?到目前为止,每当我选中任务旁边的复选框时,该布尔字段将始终为真。

请看看我的新代码并帮助我!

ToDoList.js:

$(function(){

    $("#addTaskButton").click(function(){
        var taskInput = $("#taskInputTextField").val();
        var newTask = $("<div class=\"checkbox-task\"><label class=\"task\" ><input type=\"checkbox\">" + taskInput + "</label></div>");
        if (taskInput.length === 0)
        {
            alert("There is nothing entered in the Task input field. Please enter a task before clicking on the \"Add Task\" button.");
            return false;
        }

        $.post("process-request", {new_task: taskInput});

//            $("#listOfThingsToDo").load(document.URL + ' #listOfThingsToDo');
            //$("#listOfThingsToDo").append("<div class=\"checkbox-task\"><label><input class=\"task\" type=\"checkbox\">" + data[data.length - 1].fields.task_to_do + "</label></div>");

        $("#listOfThingsToDo").append(newTask);
            $(".checkbox-task:last").hide();
            $(".checkbox-task:last").fadeIn(500);

        $(newTask).change(function(event){
            console.log($(event.target).is(':checked'));

             //$.post("modify-checked-value", {this_checkbox_is_checked: $(event.target).is(':checked'), index_of_element: $(newTask).index()});
                if ($(event.target).is(':checked'))
                {
                    $.post("modify-checked-value", {this_checkbox_is_checked: true, index_of_element: $(newTask).index()});
                    $(event.target).parent().css("text-decoration", "line-through");
                    $(event.target).attr("checked:\"checked\"");
                }
                else
                {
                     $.post("modify-checked-value", {this_checkbox_is_checked: false, index_of_element: $(newTask).index()});
                    $(event.target).parent().css("text-decoration", "none");
                    $(event.target).removeAttr("checked");
                }


        });
    });

    $("#removeAllTasksButton").click(function() {
        $.post("remove-all-tasks", null, function(data) {
            $("#listOfThingsToDo").empty();
        });
    });

    $('#listOfThingsToDo :checkbox').click(function() {
        var $this = $(this);
        console.log($this.is(':checked'));
        console.log("asdglkadfjglkadfjglkfdajgl");
        console.log($(event.target).parent().parent().index());

        //$.post("modify-checked-value", {this_checkbox_is_checked: $(event.target).is(':checked'), index_of_element: $(event.target).parent().parent().index()});

        if ($this.is(':checked')) 
        {
            $.post("modify-checked-value", {this_checkbox_is_checked: true, index_of_element: $(event.target).parent().parent().index()});
            $(event.target).parent().css("text-decoration", "line-through");
        } 
        else 
        {
            $.post("modify-checked-value", {this_checkbox_is_checked: false, index_of_element: $(event.target).parent().parent().index()});
            $(event.target).parent().css("text-decoration", "none");
            $(event.target).removeAttr("checked");
        }


    });

});

views.py:(仅附加代码)

@csrf_exempt
def modify_checked_value(request):
    checkbox_value = request.POST["this_checkbox_is_checked"]
    print("Checkbox Value: " + checkbox_value)
    checkbox_id = int(request.POST["index_of_element"])
    print(checkbox_id)
    task_to_modify = ToDoChecklistTask.objects.all()[checkbox_id]
    print("Ready to print")

    task_to_modify.task_check_marked = models.BooleanField(default = checkbox_value);
    task_to_modify.save();


    print(ToDoChecklistTask.objects.all())
    data_to_return = serializers.serialize('json', ToDoChecklistTask.objects.all());
    return HttpResponse(data_to_return, 'application/json')

ListOfTasks.html:

{% for task in task_list %}
                <div class="checkbox-task"><label class="task" {% if task.task_check_marked %} style="text-decoration: line-through"{% endif %} ><input type="checkbox" {% if task.task_check_marked %} checked="checked" {% endif %}>{{ task.task_to_do }}</label></div>
{% endfor %}

如果您需要查看更多代码,请告诉我哪些代码会丢失,我会相应地编辑我的问题。

编辑:根据要求,这里是 models.py 的代码:

from django.db import models

class ToDoChecklistTask(models.Model):
    task_to_do = models.CharField(max_length = 200)
    task_check_marked = models.BooleanField()

    def __str__(self):
        stringToReturn = "Task: " + self.task_to_do + " Is the task done? "
        if self.task_check_marked:
            stringToReturn += "Yes"
        else:
            stringToReturn += "No"
        return stringToReturn

【问题讨论】:

    标签: jquery django django-models


    【解决方案1】:

    遵循您的代码有点困难,我无法确切说明发生了什么。但是似乎有问题的一件明确的事情是依赖索引作为 checkbox_id,然后使用该值来索引ToDoChecklistTask.objects.all()。您没有显示您的模型,所以我不知道您是否定义了任何排序,但很可能是数据库以不同的顺序返回数据,因此索引不匹配。

    相反,您应该专门使用对象的 pk 值作为复选框 ID,并在通过 ToDoChecklistTask.objects.get(pk=checkbox_id) 检索项目时使用它。

    【讨论】:

    • 我更新了我的问题;我只是询问当我取消选中复选框时如何更新我的任务对象(效果是通过标签文本删除行),以便当我刷新页面时,该复选框保持未选中状态并且标签不会被划掉。我在我的网站中使用的顺序是,我添加的每个新任务总是列表中的最后一个。我添加的第一个任务是第一个任务,即使我添加了其他任务,它仍然是第一个任务。
    • 我正在使用索引来查找未选中的任务,以便我可以访问其布尔字段并将其设置为 false。第一个任务为 0,第二个任务为 1,以此类推。
    • 依赖排序仍然不是一个好主意,尤其是在使用 pk 不再复杂的情况下。
    • 你知道如何获取对象的主键吗?顺便说一句,我已经为我正在使用的模型添加了代码; ID 字段不会在那里被覆盖。在我确实为我的 BooleanField 构造函数的括号中传递了“default = False”之前,但我出于某种我不记得的原因删除了它。图片真的会更有帮助吗?
    • 等一下;如何通过jQuery传递保存在服务器中的对象的主键?这让我很困惑。
    【解决方案2】:

    我身边有人在调查这个问题,我们花了大约几个小时试图解决这个问题;我们终于找到了问题所在。我们决定从那里更新我的元素通过它们各自的主键访问的方式。

    在 modify_checked_value 函数中,我为 checkbox_value 分配 request.POST["this_checkbox_is_checked"] 的值。然后我将它分配给我的模型字段 task_check_marked。之前,我知道 checkbox_value 是一个布尔值。但是因为我使用 JSON 在 Web 浏览器和服务器之间传输数据, request.POST["this_checkbox_is_checked"] 实际上是一个字符串,而不是我期望的布尔值。

    因为 checkbox_value 被分配了一个字符串,Python 实际上被评估为 true,因此这就是为什么我注意到当我双击一个最初未选中的复选框并刷新页面时,检查出现在复选框。

    modify_checked_value 函数现在看起来像这样,因此该站点正在正常工作:

    @csrf_exempt
    def modify_checked_value(request):
        checkbox_value = request.POST["this_checkbox_is_checked"]
        checkbox_id = int(request.POST["id_of_element"])
        task_to_modify = ToDoChecklistTask.objects.get(id = checkbox_id)
    
        task_to_modify.task_check_marked = (checkbox_value == "true")
        task_to_modify.save()
    
        data_to_return = serializers.serialize('json', ToDoChecklistTask.objects.all());
        return HttpResponse(data_to_return, 'application/json')
    

    无论如何,除非你认为有必要,否则我不会发布其余的代码,因为它需要太多时间。

    【讨论】:

      猜你喜欢
      • 2015-08-18
      • 2019-04-26
      • 2019-11-04
      • 1970-01-01
      • 1970-01-01
      • 2011-08-14
      • 2012-02-08
      • 2014-02-01
      • 1970-01-01
      相关资源
      最近更新 更多