Heim >Backend-Entwicklung >Python-Tutorial >Erstellen einer To-Do-App mit Django und HTMX – Teil Hinzufügen des Todo-Modells mit TDD

Erstellen einer To-Do-App mit Django und HTMX – Teil Hinzufügen des Todo-Modells mit TDD

Mary-Kate Olsen
Mary-Kate OlsenOriginal
2025-01-04 07:05:34504Durchsuche

Dies ist der zweite Beitrag unserer Serie zum Erstellen einer Todo-App mit HTMX und Django. Klicken Sie hier für Teil 1.

In Teil 2 erstellen wir das Todo-Modell und implementieren seine Grundfunktionalität mit Unit-Tests.

Erstellen des Todo-Modells

In models.py erstellen wir das Todo-Modell mit seinen Grundattributen. Wir möchten, dass ein Todo-Element einem Benutzerprofil zugeordnet wird, sodass ein Benutzer nur seine eigenen Elemente sieht. Ein ToDo-Element hat außerdem einen Titel und das boolesche Attribut is_completed. Wir haben viele zukünftige Ideen für das Todo-Modell, wie zum Beispiel die Möglichkeit, eine Aufgabe neben der Angabe, ob sie abgeschlossen oder nicht begonnen wurde, auch auf „in Bearbeitung“ zu setzen, und Fälligkeitstermine festzulegen, aber das ist für später. Lassen Sie es uns jetzt einfach halten, um so schnell wie möglich etwas auf dem Bildschirm zu haben.

Hinweis: In einer realen App sollten wir wahrscheinlich die Verwendung von UUIDs als Primärschlüssel für die UserProfile- und Todo-Modelle in Betracht ziehen, aber wir halten es vorerst einfach.

# 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

Lassen Sie uns die Migrationen für das neue Modell ausführen:

❯ 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

Wir schreiben unsere ersten Tests

Lassen Sie uns die ersten Tests zu unserem Projekt schreiben. Wir möchten sicherstellen, dass ein Benutzer nur seine eigenen Aufgaben sieht und nicht die Elemente anderer Benutzer.

Um uns beim Schreiben der Tests zu helfen, werden wir unserem Projekt eine neue Entwicklungsabhängigkeit hinzufügen, model-bakery, die den Prozess der Erstellung von Dummy-Django-Modellinstanzen vereinfacht. Wir werden auch pytest-django hinzufügen.

❯ 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

In pyproject.toml müssen wir pytest konfigurieren, indem wir am Ende der Datei einige Zeilen hinzufügen:

# pyproject.toml

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

Jetzt schreiben wir unseren ersten Test, um sicherzustellen, dass Benutzer nur Zugriff auf ihre eigenen Aufgaben haben.

# 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"}

Wir verwenden eine conftest.py-Datei von pytest, um einen Platz für alle Fixtures zu haben, die wir in unseren Tests verwenden möchten. Die model_bakery-Bibliothek macht es einfach, Instanzen von UserProfile und Todo mit minimalem Boilerplate zu erstellen.

#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

Lass uns unsere Tests durchführen!

❯ 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

Registrieren Sie eine Admin-Seite für Todos

Endlich können wir eine Admin-Seite dafür registrieren:

# 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"]

Wir können jetzt einige Todos vom Administrator hinzufügen!

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

Wenn Sie den gesamten Code bis zum Ende von Teil 2 überprüfen möchten, können Sie ihn auf Github in der Zweigstelle Teil 02 überprüfen.

Das obige ist der detaillierte Inhalt vonErstellen einer To-Do-App mit Django und HTMX – Teil Hinzufügen des Todo-Modells mit TDD. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Stellungnahme:
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn