2

Django version=1.10.2 and python 2.7 Im learning django and trying to clone to-do list item like this Here is the models file for todo:-

class Todo(models.Model):
    title = models.CharField(max_length=200)
    # text = models.TextField()
    completed = models.BooleanField(null=False,default=False)

    created_at = models.DateTimeField(auto_now_add=True)
    def __str__(self):
        return self.title   #this makes djangoadmin page show title inthe list

The views file

from django.shortcuts import render
from models import Todo
def index(request):
    todos = Todo.objects.all()
    context = {
        'todos':todos
    }
    if request.method == 'POST':
        title = request.POST['title']
        todo = Todo(title=title)
        todo.save()
        return render(request,'index.html',context)
    else:
        return render(request,'index.html',context)

def show_completed(request): #show completed task only
    todos = Todo.objects.filter(completed=True)
    context = {
        'todos': todos
    }
    return render(request, 'index.html', context)

def show_active(request):   #show active task list
    todos = Todo.objects.filter(completed=False)
    context = {
        'todos': todos
    }
    return render(request, 'index.html', context)
def clear_completed(request):    #Delete the completed tasks
    Todo.objects.filter(completed=True).delete()
    todos = Todo.objects.all()
    context = {
        'todos': todos
    }
    return render(request, 'index.html', context)

def save_state(request):
     pass

The template file "index.html"

<!DOCTYPE html>
<html lang="en">
<head>
</head>
<body>
<h3>Todo List:</h3><hr>

<form method="post" action="{% url 'index' %}">
    {% csrf_token %}
    <input type="text" name="title" id="title"/>
    <input type="submit" value="submit" />
</form>
<hr><br>
<form method="post" action="{% url 'save_state'%}">
{% csrf_token %}
<ul>{% for todo in todos %}
    <li>  <input type="checkbox" name="completed" value="True" {% if todo.completed is True %} checked = "checked" {% endif %} >{{ todo.title }}   </li>
{% endfor %}
</ul>
 <input type="submit" value="Submit">
</form>
<a href="/todos/">All</a>
<a href="/todos/active">Active</a>
<a href="/todos/completed">Completed</a>
<a href="/todos/clear_completed">ClearCompleted</a>
</body>
</html>

I want to know how to get the checkbox's of todo items and save it if the checkbox is checked by passing those to view called "save_state"

2 Answers 2

1

Well just use javascript to call your url that you have to define, sending the todo.title. Something like :

urls.py

... # other patterns
url(r'^save_state/$', save_state, name='save_state')

whatever.js

$('input[name="completed"]').click(function(){
  data['checked'] = $(this).value()
  data['todo_title'] =  $(this).text()
  $.ajax({
    url: 'path/to/save_state',
    type: 'POST',
    data: data
  });
});

views.py

def save_state(request):
    if request.method == 'POST':
        title = request.POST.get('todo_title', '')
        checked = request.POST.get('checked', '')
        todo = Todo.objects.get(title=title)
        todo.completed = checked
        todo.save()

Please note that's a big help but not a copy paste solution : you need to adapt this js to get the actual good value, and see if the checked value is stored as string ('0' or '1') when you get it back in the save_state view.

Use click event cause it's triggered after the value changed.

EDIT If you want to use only django, you need to change your html like this:

<ul>{% for todo in todos %}
    <li>  <input type="checkbox" id="{{ todo.title }}"name="completed" value="" {% if todo.completed is True %} checked = "checked" {% endif %} >{{ todo.title }}   </li>
{% endfor %}
</ul>

And then you can get all the input in your request.POST and update. request.POST.getlists('completed') you'll get all the fields with name completed

Sign up to request clarification or add additional context in comments.

7 Comments

thank you for the answer but i have very little knowledge of javascript, is threre any way using django alone?
well if you want to use only django, you can do it by submitting the form. So the user change all he wants, and then submit the form (as you wrote it in your code). I update my answer
i used it but its giving me DoesNotExist at /todos/save_state/ Todo matching query does not exist. error
well check what title is returned in your function. You might send a wrong one, or have an input you shouldn't have. Use import pdb; pdb.set_trace()
did you find what key was missing ?
|
0

using jquery and ajax TemplateFile: index.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0-beta/css/bootstrap.min.css" integrity="sha384-/Y6pD6FV/Vv2HJnA6t+vslU6fwYXjCFtcEpHbNJ0lyAFsXTsjBbfaDjzALeQsN6M" crossorigin="anonymous">
    <title>Todo Indexpage</title>
    <script src="https://code.jquery.com/jquery-3.2.1.min.js"></script>
</head>
<body>
<div class="container">
  <div class="row">
    <div class="col-sm-4">
<h3>Todo List:</h3><hr>

{% if not request.user.is_authenticated  %}
    Please login to view the content <hr>
click <a href="/accounts/login">here</a> to login <br>
click <a href="/signup">here</a> to signup
{% endif %}

{% if request.user.is_authenticated and not user.is_superuser %}
    <h3> {{request.user.username}} is logged in <hr></h3>
<form method="post" action="{% url 'index' %}">
    {% csrf_token %}
    <input type="text" name="title" id="title" placeholder="What needs to be done?"/>
    <input type="hidden" name="author" id="author" value="{{request.user.username}}">
    <input type="submit" value="submit" hidden="hidden" />
</form>
<hr>
<br>

<ul>

{% for todo in todos %}
<li>
    <input class="todoBox" type="checkbox" id="{{ todo.title }}" name="{{ todo.title }}" value=""
         {% if todo.completed is True %} checked = "checked"
         {% endif %} >   {{ todo.title }}
</li>
{% endfor %}
</ul>

<a href="/todos/">All </a>|
<a href="/todos/active">Active </a>|
<a href="/todos/completed">Completed </a>|
<a href="/todos/clear_completed"> ClearCompleted</a>
<hr>
click <a href="/accounts/logout/">here</a> to logout
{% endif %}
<!-- for admin viewpage -->
{% if request.user.is_authenticated and user.is_superuser %}
    <h3> {{request.user.username}} is logged in (Administrator User)<hr></h3>
<form method="post" action="{% url 'index' %}">
    {% csrf_token %}
    <input type="text" name="title" id="title" placeholder="What needs to be done?"/>
    <input type="hidden" name="author" id="author" value="{{request.user.username}}">
    <input type="submit" value="submit" hidden="hidden" />
</form>
<hr>
<br>

<table>
  <tr>
    <th>Task</th>
    <th>Author</th>
  </tr>
{% for todo in todos %}
<tr > <td class="pull-left">
    <input class="todoBox" type="checkbox" id="{{ todo.title }}" name="{{ todo.title }}" value=""
         {% if todo.completed is True %} checked = "checked"
         {% endif %} >   {{ todo.title }}</td> <td class="text-right">{{ todo.author }}</td>

</tr>
{% endfor %}


<a href="/todos/">All </a>|
<a href="/todos/active">Active </a>|
<a href="/todos/completed">Completed </a>|
<a href="/todos/clear_completed"> ClearCompleted</a>
<hr>
click <a href="/accounts/logout/">here</a> to logout
{% endif %}

<script>
    $(document).ready(function()
    {
        var data = [];
        $('.todoBox').click(function()
        {
            var check = $(this).is(':checked');
            var todo_title =  $(this).attr('name');
            $.ajax
            ({
                url: "{% url 'save_state'%}",
                type: 'post',
                data: {check: check, todo_title: todo_title, csrfmiddlewaretoken: "{{ csrf_token }}"},
                success: function(html)
                {
                    console.log(html);
                }
            });
        });
    });
</script>
</body>
</html>

views.py

def save_state(request):
    print request.POST
    if request.method == 'POST':
        uname  = request.session.get('uname')
        check  = request.POST['check'] # post value either true or false
        titles = request.POST['todo_title']# post value i.e. name of title
    for title in Todo.objects.filter(title=titles):
        # return HttpResponse(title.title)
            title.completed = check.title() # title() capitalizes first letter of string
            title.save()
    return HttpResponse('data is saved')

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.