This is the second post of our series on how to build a Todo app using HTMX and Django. , which simplifies the process of creating dummy Django model instances. We'll also add 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
In pyproject.toml we need to configure pytest, by adding some lines at the end of the file:
# pyproject.toml
# NEW
[tool.pytest.ini_options]
DJANGO_SETTINGS_MODULE = "todomx.settings"
python_files = ["test_*.py", "*_test.py", "testing/python/*.py"]
Now let's write our first test to ensure users only have access to their own todos.
# 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"}
We're using a conftest.py file from pytest to have a place for all fixtures we plan to use in our tests. The model_bakery library makes it simple to create instances of UserProfile and Todo with minimal boilerplate.
#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
Let's run our 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
Register an admin page for Todos
Finally, we can register an admin page for it:
# 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"]
We can now add some Todo's from admin!

SOCIAL SHARE CARD GENERATOR