Completing and deleting tasks - 30 days of Django

Completing and deleting tasks - 30 days of Django

/ #Django


Let's work more with the tasks. It's time to make it possible to completing and deleting tasks.

Mark as done / completed

The first thing I want to do for making it possible to complete a task, is to create a new view. Open up "task/views.py" and add this new view:

def mark_completed(request, pk):
    task = Task.objects.get(pk=pk)
    task.is_done = True
    task.save()

    return redirect('frontpage')

So that was really easy, huh?
We just get the task from the database based on the id/pk in the url, then we set the "is_done" field to "True" and redirect the user back to th front page.

Before we can use this, we also need to append the view to "task/urls.py" like this:

from django.urls import path

from . import views

urlpatterns = [
    path('', views.frontpage, name='frontpage'),
    path('edit_task/<int:pk>/', views.edit_task, name='edit_task'),
    path('mark_completed/<int:pk>/', views.mark_completed, name='mark_completed'), # New
]

This should look familiar. It's just a simple primary key inside the path, and then we point to the view. Next and last step is to update template to link to this path. In the loop where we show the tasks, do this:

{% for task in tasks %}
    <div>
        <p>
            {{ task.title }}
            -
            <a href="{% url 'edit_task' task.id %}">Edit</a>
            -
            {% if task.is_done %}
                Completed
            {% else %}
                <a href="{% url 'mark_completed' task.id %}">Mark complete</a>
            {% endif %}
        </p>
    </div>
{% endfor %}

So here is a little bit of new code. We're using an if-statement to check if the is_done field is set to true or not. If the value is true, we just show a label saying "Completed". But it the value is false, then we show a link which will be used for marking the task as done.

Deleting tasks

The procedure for deleting the tasks is almost the same. Let's begin with the view.

def delete_task(request, pk):
    task = Task.objects.get(pk=pk)
    task.delete()

    return redirect('frontpage')

So here we do almost the same thing as in the other view, the only difference is that we call a function called "delete()" on the task object. And Django will handle the rest for us. Let's add it to the url patterns:

from django.urls import path

from . import views

urlpatterns = [
    path('', views.frontpage, name='frontpage'),
    path('edit_task/<int:pk>/', views.edit_task, name='edit_task'),
    path('mark_completed/<int:pk>/', views.mark_completed, name='mark_completed'),
    path('delete_task/<int:pk>/', views.delete_task, name='delete_task'), # New
]

Last step then is to add a link for this in the loop at the front page again:

{% for task in tasks %}
    <div>
        <p>
            {{ task.title }}
            -
            <a href="{% url 'edit_task' task.id %}">Edit</a>
            -
            {% if task.is_done %}
                Completed
            {% else %}
                <a href="{% url 'mark_completed' task.id %}">Mark complete</a>
            {% endif %}
            -
            <a href="{% url 'delete_task' task.id %}">Delet</a>
        </p>
    </div>
{% endfor %}

Go ahead and test it out. We should now be able to mark tasks as completed and we can also delete them if we wanted to.

--

Table of contents

Comments

No comments yet...

Add comment

Newsletter

Subscribe to my weekly newsletter. One time per week I will send you a short summary of the tutorials I have posted in the past week.