Maison >développement back-end >Tutoriel Python >Création d'une application To-Do avec Django et HTMX - Partie Ajout du modèle Todo avec TDD

Création d'une application To-Do avec Django et HTMX - Partie Ajout du modèle Todo avec TDD

Mary-Kate Olsen
Mary-Kate Olsenoriginal
2025-01-04 07:05:34504parcourir

Ceci est le deuxième article de notre série sur la façon de créer une application Todo en utilisant HTMX et Django. Cliquez ici pour la partie 1.

Dans la partie 2, nous créerons le modèle Todo et implémenterons ses fonctionnalités de base avec des tests unitaires.

Création du modèle Todo

Dans models.py créons le modèle Todo, avec ses attributs de base. Nous souhaitons qu'un élément Todo soit associé à un profil utilisateur, afin qu'un utilisateur ne voie que ses propres éléments. Un élément de tâche aura également un titre et un attribut booléen is_completed. Nous avons beaucoup d'idées futures pour le modèle Todo, comme la possibilité de définir une tâche comme "en cours" en plus d'être terminée ou non commencée, et des dates d'échéance, mais c'est pour plus tard. Gardons les choses simples maintenant pour avoir quelque chose à l'écran dès que possible.

Remarque : dans une application réelle, nous devrions probablement envisager d'utiliser les UUID comme clés primaires sur les modèles UserProfile et Todo, mais nous allons garder les choses simples pour le moment.

# core/models.py

from django.contrib.auth.models import AbstractUser
from django.db import models  # <-- NEW

class UserProfile(AbstractUser):
    pass

# NEW
class Todo(models.Model):
    title = models.CharField(max_length=255)
    is_completed = models.BooleanField(default=False)
    user = models.ForeignKey(
        UserProfile,
        related_name="todos",
        on_delete=models.CASCADE,
    )
    created_at = models.DateTimeField(auto_now_add=True)
    updated_at = models.DateTimeField(auto_now=True)

    def __str__(self):
        return self.title

Exécutons les migrations pour le nouveau modèle :

❯ uv run python manage.py makemigrations
Migrations for 'core':
  core/migrations/0002_todo.py
    + Create model Todo
❯ uv run python manage.py migrate
Operations to perform:
  Apply all migrations: admin, auth, contenttypes, core, sessions
Running migrations:
  Applying core.0002_todo... OK

Rédaction de nos premiers tests

Écrivons les premiers tests sur notre projet. Nous voulons nous assurer qu'un utilisateur ne verra que ses propres tâches, et non les éléments des autres utilisateurs.

Pour nous aider à écrire les tests, nous ajouterons une nouvelle dépendance de développement à notre projet, model-bakery, qui simplifie le processus de création d'instances factices de modèle Django. Nous ajouterons également pytest-django.

❯ uv add model-bakery pytest-django --dev
Resolved 27 packages in 425ms
Installed 2 packagez in 12ms
 + model-bakery==1.20.0
 + pytest-django==4.9.0

Dans pyproject.toml nous devons configurer pytest, en ajoutant quelques lignes à la fin du fichier :

# pyproject.toml

# NEW
[tool.pytest.ini_options]
DJANGO_SETTINGS_MODULE = "todomx.settings"
python_files = ["test_*.py", "*_test.py", "testing/python/*.py"]

Écrivons maintenant notre premier test pour garantir que les utilisateurs n'ont accès qu'à leurs propres tâches.

# core/tests/test_todo_model.py

import pytest


@pytest.mark.django_db
class TestTodoModel:
    def test_todo_items_are_associated_to_users(self, make_todo, make_user):
        [user1, user2] = make_user(_quantity=2)

        for i in range(3):
            make_todo(user=user1, title=f"user1 todo {i}")

        make_todo(user=user2, title="user2 todo")

        assert {todo.title for todo in user1.todos.all()} == {
            "user1 todo 0",
            "user1 todo 1",
            "user1 todo 2",
        }

        assert {todo.title for todo in user2.todos.all()} == {"user2 todo"}

Nous utilisons un fichier conftest.py de pytest pour avoir une place pour tous les appareils que nous prévoyons d'utiliser dans nos tests. La bibliothèque model_bakery facilite la création d'instances de UserProfile et Todo avec un minimum de passe-partout.

#core/tests/conftest.py

import pytest
from model_bakery import baker


@pytest.fixture
def make_user(django_user_model):
    def _make_user(**kwargs):
        return baker.make("core.UserProfile", **kwargs)

    return _make_user


@pytest.fixture
def make_todo(make_user):
    def _make_todo(user=None, **kwargs):
        return baker.make("core.Todo", user=user or make_user(), **kwargs)

    return _make_todo

Faisons nos tests !

❯ uv run pytest
Test session starts (platform: darwin, Python 3.12.8, pytest 8.3.4, pytest-sugar 1.0.0)
django: version: 5.1.4, settings: todomx.settings (from ini)
configfile: pyproject.toml
plugins: sugar-1.0.0, django-4.9.0
collected 1 item

 core/tests/test_todo_model.py ✓                                                                                                                                   100% ██████████

Results (0.25s):
       1 passed

Enregistrez une page d'administration pour Todos

Enfin, nous pouvons enregistrer une page d'administration pour cela :

# core/admin.py

from django.contrib import admin
from django.contrib.auth.admin import UserAdmin
from .models import Todo, UserProfile # <-- NEW

# .. previous code

# NEW
@admin.register(Todo)
class TodoAdmin(admin.ModelAdmin):
    model = Todo
    list_display = ["title", "is_completed", "user"]
    list_filter = ["is_completed"]
    search_fields = ["title"]
    list_per_page = 10
    ordering = ["title"]

Nous pouvons maintenant ajouter quelques tâches depuis l'administrateur !

Creating a To-Do app with Django and HTMX - Part Adding the Todo model with TDD

Si vous souhaitez vérifier l'intégralité du code jusqu'à la fin de la partie 2, vous pouvez le vérifier sur Github à la branche partie 02.

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Déclaration:
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn