Home >Backend Development >Python Tutorial >Get Done ✅ : A step-by-step guide in building a Django To Do List

Get Done ✅ : A step-by-step guide in building a Django To Do List

Patricia Arquette
Patricia ArquetteOriginal
2025-01-06 06:20:40931browse

Get Done ✅ : A step-by-step guide in building a Django To Do List

Introduction

Managing tasks effectively is crucial in our busy lives, and a to-do list application can be an excellent tool for staying organized. This blog post walks you through the development of a to-do list application using Django, a powerful and versatile web framework in Python. The project, titled django-todoList, is designed to help users create, manage, and track their daily tasks seamlessly.

Prerequisites

Before we begin, ensure that you have the following:

  • Python installed (preferably version 3.8 or above).

  • Django installed. If not, you can install it using the following command.

pip install django
  • A basic understanding of how Django works and familiarity with Python and HTML.

Step 1: Setting Up the Project

1.1 Create a Django Project

First, create a new Django project using the command:

django-admin startproject mysite

Navigate into your project folder:

cd mysite

1.2 Create a Django App

Next, create an app within the project. We’ll call it todoList:

python manage.py startapp todoList

Step 2: Define Models

In Django, models are used to define the structure of your data. For the GetDone To-Do app, we need a model to represent a Task.

Navigate to todoList/models.py and define the Task model:

from django.db import models
from django.contrib.auth.models import User

class Task(models.Model):
    title = models.CharField(max_length=200)
    description = models.TextField()
    complete = models.BooleanField(default=False)
    created = models.DateTimeField(auto_now_add=True)
    deadline = models.DateTimeField(null=True, blank=True)
    user = models.ForeignKey(User, on_delete=models.CASCADE)

    def __str__(self):
        return self.title

This model includes fields like title, description, deadline, and complete to store details of each task. We also associate each task with a user via the user foreign key.

2.1 Migrate the Database

Once the model is ready, run the migrations to create the table for this model in the database:

python manage.py makemigrations
python manage.py migrate

Step 3: Create Forms

We need forms to handle user input for creating and updating tasks. In todoList/forms.py, create the TaskForm:

from django import forms
from .models import Task

class TaskForm(forms.ModelForm):
    class Meta:
        model = Task
        fields = ['title', 'description', 'deadline', 'complete']
        widgets = {
            'title': forms.TextInput(attrs={'placeholder': 'Enter task title'}),
            'description': forms.Textarea(attrs={'placeholder': 'Enter task description', 'rows': 4}),
            'deadline': forms.DateTimeInput(attrs={'type': 'datetime-local'}),
            'complete': forms.CheckboxInput(),
        }

    def clean_title(self):
        title = self.cleaned_data.get('title')
        if not title:
            raise forms.ValidationError('Title is required')
        return title

    def clean_description(self):
        description = self.cleaned_data.get('description')
        if not description:
            raise forms.ValidationError('Description is required')
        return description

    def clean_deadline(self):
        deadline = self.cleaned_data.get('deadline')
        if not deadline:
            raise forms.ValidationError('Deadline is required')
        return deadline

The TaskForm uses Django’s ModelForm to automatically create form fields for the Task model.

Step 4: Define Views

Next, we need to create views to handle user requests, such as creating tasks, updating them, and listing them.

In todoList/views.py, define the views:

from django.shortcuts import render, redirect
from django.views.generic import ListView, CreateView, UpdateView, DeleteView
from django.contrib.auth.views import LoginView
from django.contrib.auth.mixins import LoginRequiredMixin
from django.contrib.auth.forms import UserCreationForm
from django.urls import reverse_lazy
from .models import Task
from .forms import TaskForm
from django.contrib import messages
from django.utils import timezone


# Task List View
class TodoListView(LoginRequiredMixin, ListView):
    model = Task
    context_object_name = 'tasks'
    template_name = 'task_list.html'

    def get_context_data(self, **kwargs):
        context = super().get_context_data(**kwargs)
        user_tasks = Task.objects.filter(user=self.request.user)
        context['tasks'] = Task.objects.filter(user=self.request.user)
        context['incomplete_tasks_count'] = user_tasks.filter(complete=False).count()  # Count incomplete tasks
        context['now'] = timezone.now()
        return context

# Task Create View
class TaskCreate(LoginRequiredMixin, CreateView):
    model = Task
    form_class = TaskForm
    template_name = 'todoList/task_create.html'
    success_url = reverse_lazy('todoList')

    def form_valid(self, form):
        form.instance.user = self.request.user
        messages.success(self.request, 'Task created successfully!')
        return super(TaskCreate, self).form_valid(form)

# Task Update View
class TaskUpdate(LoginRequiredMixin, UpdateView):
    model = Task
    form_class = TaskForm
    template_name = 'todoList/task_update.html'
    success_url = reverse_lazy('todoList')
    def form_valid(self, form):
        messages.success(self.request, 'Task updated successfully!')
        return super(TaskUpdate, self).form_valid(form)

# Task Delete View
class TaskDelete(LoginRequiredMixin, DeleteView):
    model = Task
    context_object_name = 'task'
    template_name = 'todoList/task_delete.html'
    success_url = reverse_lazy('todoList')
    def dispatch(self, request, *args, **kwargs):
        response = super().dispatch(request, *args, **kwargs)
        if response.status_code == 302:
            messages.success(self.request, 'Task deleted successfully!')
        return response

# User Registration View
class RegisterView(CreateView):
    form_class = UserCreationForm
    template_name = 'todoList/register.html'
    success_url = reverse_lazy('todoList')

    def form_valid(self, form):
        response = super().form_valid(form)
        # Log the user in after successful registration
        from django.contrib.auth import login
        login(self.request, self.object)
        messages.success(self.request, 'Registration successful! Welcome!')
        return response


# Login View
class CustomLoginView(LoginView):
    template_name = 'todoList/login.html'
    fields = '__all__'
    redirect_authenticated_user = True

    def get_success_url(self):
        messages.success(self.request, 'You have logged in successfully!')
        return reverse_lazy('todoList')

-TodoListView: Lists all tasks for the logged-in user.
-TaskCreate: Handles task creation.
-TaskUpdate: Allows users to update a task.
-TaskDelete: Provides a confirmation page for deleting a task.
T-he LoginRequiredMixin ensures that only logged-in users can access these views.

Step 5: Configure URLs

In todoList/urls.py, map URLs to their respective views:

pip install django

These URL patterns will map each view to a specific URL. For example, the task list is displayed at the root URL of the app, and users can create, edit, or delete tasks by visiting specific URLs.

Step 6: Create Templates

Create the following HTML templates to render the views:

6.1 base.html

The base template provides a consistent layout for all pages:

django-admin startproject mysite

Step 8: Add User Authentication

In views.py, you can use Django’s built-in user authentication views to handle user registration and login. For example, you can use UserCreationForm to allow users to sign up:

cd mysite

Step 8: Run the Server

Once everything is set up, you can run the server:

python manage.py startapp todoList

Visit http://127.0.0.1:8000/todoList to see your To-Do List app in action!

Understanding settings.py and urls.py in the mysite Folder

settings.py

The settings.py file is a crucial part of every Django project. It contains the configuration settings for your project, such as database settings, installed apps, middleware, static files configuration, and more. This file controls the behavior of your project and allows Django to connect the dots between various components.

Here's a brief overview of key settings in settings.py for your GetDone To-Do List app:

Key Sections in settings.py:

Installed Apps: In the INSTALLED_APPS list, you register all the apps used in your project. For instance:

from django.db import models
from django.contrib.auth.models import User

class Task(models.Model):
    title = models.CharField(max_length=200)
    description = models.TextField()
    complete = models.BooleanField(default=False)
    created = models.DateTimeField(auto_now_add=True)
    deadline = models.DateTimeField(null=True, blank=True)
    user = models.ForeignKey(User, on_delete=models.CASCADE)

    def __str__(self):
        return self.title

Here, we’ve added todoList, which is the app that manages the tasks, alongside the default apps provided by Django for user authentication, admin panel, and static files.

urls.py

In Django, the urls.py file handles the routing of HTTP requests to views. It is where you map URL patterns (such as /tasks/, /login/) to corresponding views that will handle them.

In the mysite/urls.py, you usually include URLs for the whole project and link them to the app-level urls.py file.

Here’s what urls.py looks like in your GetDone app:

Key Sections in urls.py:

Project-Level urls.py (mysite/urls.py): The urls.py file in the mysite folder is the main router for your entire Django project. It includes the URLs for the admin panel, authentication, and links to your app's specific URLs. Here’s an example:

pip install django

path('admin/', admin.site.urls): This line includes the Django admin panel.
path('accounts/', include('django.contrib.auth.urls')): This includes built-in authentication URLs for login, logout, and password management.
path('', include('todoList.urls')): This includes the app-specific URLs (defined in todoList/urls.py), so users can navigate through tasks and other features.
App-Level urls.py (todoList/urls.py): This file maps specific URLs to views within the todoList app. It contains paths for viewing tasks, creating tasks, and other task-related actions. For example:

django-admin startproject mysite

TodoListView.as_view(): This view lists all tasks for the logged-in user.
TaskCreate.as_view(): This view handles the task creation form.
TaskUpdate.as_view(): This view handles the task update form.
TaskDelete.as_view(): This view handles the task deletion confirmation page.

Communication Between Files

Django’s architecture allows for smooth communication between the different files and components:

URLs and Views:

The urls.py maps URLs to views, such as task creation or list viewing. Views are defined in views.py.

Models and Views:

Views interact with models (defined in models.py) to retrieve and manipulate data (tasks). For example, in TodoListView, the view fetches tasks associated with the logged-in user using Task.objects.filter(user=self.request.user).

Forms and Views:

Forms (like TaskForm in forms.py) handle user input and interact with models to validate and save the data.

Templates:

Templates render the final output in HTML, displaying data passed from views and handling user input through forms.

Conclusion

With these steps, you’ve built a fully functional To-Do list app using Django. You’ve implemented user authentication, task management (create, edit, delete), and learned how Django’s MVC (MTV) architecture facilitates the smooth communication between models, views, templates, and URLs. This guide serves as a solid foundation for building more complex Django applications in the future.

Full code of the application is available to clone at

cd mysite

Happy coding! ?

The above is the detailed content of Get Done ✅ : A step-by-step guide in building a Django To Do List. For more information, please follow other related articles on the PHP Chinese website!

Statement:
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn