Lädt...

🔧 Creating a To-Do app with Django and HTMX - Part 1: Creating the Django project with uv


Nachrichtenbereich: 🔧 Programmierung
🔗 Quelle: dev.to

In this series of posts we will create a To-Do app using HTMX and Django, following a TDD (Test-driven development) workflow.

The goal of this series of posts is to document my own learning process of using HTMX with Django.

The app will start with a textbox on top to add to-do items, and a list of current to-do items as horizontal components. The first version will simply support the creation and completion of the items.

The next two features we want to have is the concept of due dates and a sidebar which allows us to filter by tasks due today, tomorrow and overdue, and the use of natural language to add to-do items, for example writing "Call doctor tomorrow 8:30" should create an item with the title "Call doctor" and due date on the next day at 8:30 AM.

These are the types of features that can benefit immensely from TDD as it allows us to focus on how to process natural language while not worrying too much on how to integrate it with the frontend.

Prototype of the UI of the to-do app, with a textbox on top, a button with text

Creating the project using uv

We will kickoff the project using uv, which is defined on its website as

"An extremely fast Python package and project manager, written in Rust [...] a single tool to replace pip, pip-tools, pipx, poetry, pyenv, twine, virtualenv, and more."

I am particularly interested on having a simple way to manage dependencies using pyproject.toml and a virtual environment.

To install uv on your machine, follow the instructions in its website.

❯ uv init
Initialized project `todo-mx`
❯ uv venv
Using CPython 3.12.8
Creating virtual environment at: .venv
Activate with: source .venv/bin/activate
❯ source .venv/bin/activate

Now that we have a project and a virtual environment we can add our first two dependencies: Django and pytest. We're also adding an optional dependency, pytest-sugar, which provides a nicer interface to our tests.

❯ uv add django
Resolved 5 packages in 248ms
Installed 3 packages in 350ms
 + asgiref==3.8.1
 + django==5.1.4
 + sqlparse==0.5.3
❯ uv add pytest pytest-sugar --dev
Resolved 12 packages in 206ms
Installed 6 packages in 14ms
 + iniconfig==2.0.0
 + packaging==24.2
 + pluggy==1.5.0
 + pytest==8.3.4
 + pytest-sugar==1.0.0
 + termcolor==2.5.0

Creating the django project

To create the Django project in the current directory, we can run the following uv command:

uv run django-admin startproject todomx .

Note: We're preprending the command with uv run to ensure that we will always run the commands in the correct virtual environment for the project; it's a good habit to develop when we're dealing with several projects and environments, but it's not mandatory.

We can ensure that the installation worked by running the runserver command:

❯ uv run python manage.py runserver
Watching for file changes with StatReloader
Performing system checks...

System check identified no issues (0 silenced).

You have 18 unapplied migration(s). Your project may not work properly until you apply the migrations for app(s): admin, auth, contenttypes, sessions.
Run 'python manage.py migrate' to apply them.
January 01, 2025 - 16:12:00
Django version 5.1.4, using settings 'todomx.settings'
Starting development server at http://127.0.0.1:8000/
Quit the server with CONTROL-C.

Opening the link shows us the Django welcome screen

Home page for Django with the text

Overriding the default user authentication model

Before we run the pending migrations, as suggested when we executed the runserver command, we will override Django's default user model, which is a best-practice for new projects. There's a lot of literature on why this is a good idea, including the official documentation.

Later we may want to incorporate django-allauth in the project, but we want to keep it simple and have something up and running soon, so let's just create an app called core, create a UserProfile class inheriting from AbstractUser, and set our project to use this class as its authentication model.

❯ uv run python manage.py startapp core

Let's add the model in core/models.py:

from django.contrib.auth.models import AbstractUser

class UserProfile(AbstractUser):
    pass

In settings.py, let's add our new app and change the authentication user model:


INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'core', # <-- NEW
]

AUTH_USER_MODEL = 'core.UserProfile' # <-- NEW

We can now make the migrations, apply them, and create a superuser for the app:

❯ uv run python manage.py makemigrations
Migrations for 'core':
  core/migrations/0001_initial.py
    + Create model UserProfile
❯ uv run python manage.py migrate
Operations to perform:
  Apply all migrations: admin, auth, contenttypes, core, sessions
Running migrations:
  Applying contenttypes.0001_initial... OK
  Applying contenttypes.0002_remove_content_type_name... OK
  Applying auth.0001_initial... OK
  Applying auth.0002_alter_permission_name_max_length... OK
  Applying auth.0003_alter_user_email_max_length... OK
  Applying auth.0004_alter_user_username_opts... OK
  Applying auth.0005_alter_user_last_login_null... OK
  Applying auth.0006_require_contenttypes_0002... OK
  Applying auth.0007_alter_validators_add_error_messages... OK
  Applying auth.0008_alter_user_username_max_length... OK
  Applying auth.0009_alter_user_last_name_max_length... OK
  Applying auth.0010_alter_group_name_max_length... OK
  Applying auth.0011_update_proxy_permissions... OK
  Applying auth.0012_alter_user_first_name_max_length... OK
  Applying core.0001_initial... OK
  Applying admin.0001_initial... OK
  Applying admin.0002_logentry_remove_auto_add... OK
  Applying admin.0003_logentry_add_action_flag_choices... OK
  Applying sessions.0001_initial... OK
❯ uv run python manage.py createsuperuser
Username: admin
Email address: [email protected]
Password:
Password (again):
This password is too short. It must contain at least 8 characters.
This password is too common.
This password is entirely numeric.
Bypass password validation and create user anyway? [y/N]: y
Superuser created successfully.
❯

Running the app again with runserver and opening localhost:8000/admin will show us Django's admin page:

Django admin site

To wrap up part 1, we can register an admin view for UserProfile, :

# core/admin.py

from django.contrib import admin
from django.contrib.auth.admin import UserAdmin
from .models import UserProfile

@admin.register(UserProfile)
class UserProfileAdmin(UserAdmin):
    model = UserProfile
    list_display = ['email', 'username']

Refreshing the admin site will show us the admin interface for users

User admin in the main page of the admin site

User admin page in the admin site

That's it for the initial setup of our project! In part 2, we will use TDD to implement the first version of the Todo model, and setup a Github action to run the unit tests when we push the code to Github.

...

🔧 Django, Htmx e React: usando HTMX para além de TODO-Lists


📈 44.26 Punkte
🔧 Programmierung

🔧 HTMX + Go : Build a CRUD App with Golang and HTMX


📈 40.19 Punkte
🔧 Programmierung

🔧 htmx.php – Advanced HTMX Helper for PHP


📈 36.06 Punkte
🔧 Programmierung

🔧 Personal Finance Management App with Django, HTMX, Alpine, Tailwind and Plaid


📈 30.35 Punkte
🔧 Programmierung

🔧 Grok 3: AI Thông Minh Nhất Thế Giới


📈 29.79 Punkte
🔧 Programmierung

🕵️ Kèo Thẻ Phạt Vip66 Là Gì? 3 Lối Đánh Kèo Chậm Mà Chắc


📈 29.79 Punkte
🕵️ Reverse Engineering

🔧 KISS Principle: Giữ Mọi Thứ Đơn Giản Nhất Có Thể


📈 29.79 Punkte
🔧 Programmierung

🔧 Có thể bạn chưa biết (Phần 1)


📈 29.79 Punkte
🔧 Programmierung

🔧 AI-Powered Cover Letter Generator with Django, HTMX, and Gemini


📈 27.59 Punkte
🔧 Programmierung

🔧 AI Cover Letter Generator with Django, HTMX, and Gemini


📈 27.59 Punkte
🔧 Programmierung

🔧 Build a One-Product Shop With the Python Django Framework and Htmx


📈 27.59 Punkte
🔧 Programmierung

🔧 How to set up HTMX in Django


📈 26.23 Punkte
🔧 Programmierung

🔧 Django News #175- htmx 1.9.0 released


📈 26.23 Punkte
🔧 Programmierung

🔧 How to build a Task Manager using Django + HTMX


📈 26.23 Punkte
🔧 Programmierung

🔧 Why Django + HTMX + Alpine.js is a better fit for content-driven sites than a JavaScript framework


📈 26.23 Punkte
🔧 Programmierung

🔧 Creating a CRUD Application With Express and HTMX


📈 25.84 Punkte
🔧 Programmierung

🔧 Announcing my new Django package: django-admin-export! #packaging #python #django


📈 24.6 Punkte
🔧 Programmierung

🔧 HTMX vs. React: Choosing The Right Frontend Approach For Your Project


📈 23.36 Punkte
🔧 Programmierung

🔧 htmx vs. React: Choosing the right library for your project


📈 23.36 Punkte
🔧 Programmierung

🔧 Building Raku Codeboard: A Simple Full-Stack App with Red, Cromponent, and HTMX


📈 22.15 Punkte
🔧 Programmierung

🔧 Building a Dynamic Todo App with FastAPI and HTMX


📈 22.15 Punkte
🔧 Programmierung

🔧 I've built the TodoMVC app with HTMX and lived to tell the story


📈 22.15 Punkte
🔧 Programmierung

🔧 A minimalist newsletter signup app with HTMX and Manifest


📈 22.15 Punkte
🔧 Programmierung

🔧 How to Build a Real-Time Chat App With Go, Fiber and HTMX


📈 22.15 Punkte
🔧 Programmierung

🔧 Build a Full-stack App with Node.js and htmx


📈 22.15 Punkte
🔧 Programmierung

🔧 Host a Django project documentation autogenerated with Sphinx on Read the Docs -- Django specifics


📈 21.72 Punkte
🔧 Programmierung

🕵️ Low CVE-2021-21416: Django-registration project Django-registration


📈 21.72 Punkte
🕵️ Sicherheitslücken

🕵️ Medium CVE-2019-10682: Django-nopassword project Django-nopassword


📈 21.72 Punkte
🕵️ Sicherheitslücken

🔧 🚀 LibreAI: A Self-Hostable, Privacy-First AI Chat App Built with Go + HTMX


📈 20.8 Punkte
🔧 Programmierung