Checkbox booleanfield modelform in Django

So I’m making a to-do list and I made a booleanfield modelform which has attribute “complete”. I want that user to check it when it’s complete and I tried wriring if task.complete == True cross out the item and it didn’t work(it only worked when I checked it from the admin panel). Then I tried form.complete instead of task.complete and it doesn’t do anything.

models:

class Task(models.Model):
    title = models.CharField(max_length=200)
    complete = models.BooleanField(default=False)
    created = models.DateTimeField(auto_now_add=True)

    def __str__(self):
        return self.title

forms:

from .models import *

class TaskForm(forms.ModelForm):
    title = forms.CharField(widget= forms.TextInput(attrs={'placeholder':'Add new task...'}))
    class Meta:
        model = Task
        fields = '__all__'

views:

def index(request):
    tasks = Task.objects.order_by('-created')
    form = TaskForm()

    if request.method == 'POST':
        form = TaskForm(request.POST)
        if form.is_valid():
            form.save()
        return redirect('/')

    context = {
        'tasks': tasks,
        'form': form,
    }
    return render(request, 'to-do.html', context)

html:

<div class="main-container">
            <form method="POST" action="/">
                {% csrf_token %}
                <input type="submit"/>
                {{ form.title }}
            </form>
            {% for task in tasks %}
              {{ form.complete }}
              {% if form.complete == True %}
                <h1><strike>{{task.title}}</strike></h1>
              {% else %}
                <h1>{{task.title}}</h1>
              {% endif %}

            {% endfor %}
        </div>

Your checkbox fields are outside the form, and so are not going to be submitted when the button is clicked. Only the fields between the <form> and </form> tags get submitted.

I tried doing it like this but it’s still not working

                {% for task in tasks %}
                  <form method="POST" action="/">
                    {% csrf_token %}
                    {{ form.complete }}
                  </form>

                    {% if form.complete == True %}
                      <h1><strike>{{task.title}}</strike></h1>
                    {% else %}
                      <h1>{{task.title}}</h1>
                    {% endif %}

                {% endfor %}

should I fix it in views? for example:

complete = form.cleaned_data['complete']
    if complete:
       **cross out the task**

but how should I do that?

Now you’ve created a different problem. You’re creating one form for each task.

Take a look at the screenshot I posted with the question. I want tasks, which are already added to the list, to have the checkbox. If I check it, it should cross out. How else can I do that?

You’ve got to fix your template.

You need to create one form, and within that form you need to render all the elements within that form.

Your non-template code that you posted at the top is ok - don’t change anything other than the template until you’ve got your template correct. If you need an example, review the Django Tutorial page that shows basically what you’re trying to achieve here.

I copied it all into one form, but it still doesn’t get crossed, but the checkbox stays checked when I click and refresh.

              <form method="POST" action="/">
                      {% csrf_token %}
                      <input type="submit"/>
                      {{ form.title }}

                  {% for task in tasks %}
                      {% csrf_token %}
                      {{ form.complete }}

                      {% if task.complete == True %}
                        <h1><strike>{{task.title}}</strike></h1>
                      {% else %}
                        <h1>{{task.title}}</h1>
                      {% endif %}

                  {% endfor %}
                </form>

If I made a guess here, I’d say you’re testing this with just one entry. You still have an issue of what you’re creating for your context in your view.

In your template, you’re rendering a variable named “form.complete”. How many instances of “form” are you supplying to the template?

I have “form.title” and “form.complete”

Yes, those are the variables being rendered. But how many “form” are you supplying?

do you mean “form” html tags or form fields?

Neither, I’m talking about instances of the object named “form”.

You’re passing a list of “task” objects named “tasks” into the template. So I’m asking how many “form” objects you’re sending in.

yeah I have list of tasks but should I give instance to form object too?

To answer the question I posed, you’re only sending one “form” to the template.

If you have multiple tasks, you need a check box for each one - not using the same checkbox for all tasks, which does mean multiple “form” instances.

okay, but I don’t know how to do that

Well, that gets into more details than what’s practical to provide in a forum like this.

Django specifically provides a facility for handling repeated instances of a form on a page - see
Formsets. However, I also know that formsets aren’t the easiest thing to understand if you’re not really comfortable with Django forms.

If you search on Google for a “Django To Do App”, you’re likely to find a number of tutorials and blogs on the topic - one or more of which might have some samples you can draw from.

yeah I’m just trying to get comfortable with forms so I’ll try something. thanks