ایجاد یک برنامه To-Do با Django و HTMX – قسمت 1: ایجاد پروژه جنگو با uv

در این سری از پستها، ما یک برنامه To-Do با استفاده از HTMX و Django ایجاد میکنیم، به دنبال یک گردش کاری TDD (توسعه مبتنی بر آزمایش).
هدف این سری از پست ها مستندسازی فرآیند یادگیری خودم در استفاده از HTMX با جنگو است.
برنامه با یک جعبه متن در بالا برای اضافه کردن موارد انجام کار و لیستی از موارد فعلی به عنوان اجزای افقی شروع می شود. نسخه اول به سادگی از ایجاد و تکمیل موارد پشتیبانی می کند.
دو ویژگی بعدی که میخواهیم داشته باشیم، مفهوم سررسید و نوار کناری است که به ما امکان میدهد وظایف امروز، فردا و عقب افتاده را فیلتر کنیم، و استفاده از زبان طبیعی برای اضافه کردن موارد انجام کار، به عنوان مثال نوشتن “با دکتر تماس بگیرید”. فردا ساعت 8:30″ باید آیتمی با عنوان “با پزشک تماس بگیرید” و تاریخ سررسید روز بعد ساعت 8:30 صبح ایجاد کنید.
اینها انواع ویژگیهایی هستند که میتوانند از TDD بسیار سود ببرند، زیرا به ما امکان میدهد روی نحوه پردازش زبان طبیعی تمرکز کنیم و در عین حال نگران نحوه ادغام آن با قسمت جلو نباشیم.
ایجاد پروژه با استفاده از uv
ما پروژه را با استفاده از آن آغاز خواهیم کرد uv
، که در وب سایت آن به صورت تعریف شده است
یک بسته بسیار سریع پایتون و مدیر پروژه، که به زبان Rust نوشته شده است […] یک ابزار واحد برای جایگزینی pip، pip-tools، pipx، poetry، pyenv، twine، virtualenv و موارد دیگر.”
من به ویژه علاقه مند به داشتن یک راه ساده برای مدیریت وابستگی ها با استفاده از آن هستم pyproject.toml
و محیط مجازی
برای نصب uv بر روی دستگاه خود، دستورالعمل های موجود در وب سایت آن را دنبال کنید.
❯ 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
اکنون که یک پروژه و یک محیط مجازی داریم، میتوانیم دو وابستگی اول خود را اضافه کنیم: جنگو و pytest. ما همچنین یک وابستگی اختیاری به نام pytest-sugar اضافه میکنیم که رابط کاربری بهتری برای تستهای ما فراهم میکند.
❯ 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
ایجاد پروژه جنگو
برای ایجاد پروژه جنگو در دایرکتوری فعلی، میتوانیم دستور uv زیر را اجرا کنیم:
uv run django-admin startproject todomx .
توجه: ما دستور را با uv run
برای اطمینان از اینکه ما همیشه دستورات را در محیط مجازی صحیح برای پروژه اجرا خواهیم کرد. زمانی که با چندین پروژه و محیط سروکار داریم، ایجاد عادت خوبی است، اما اجباری نیست.
ما می توانیم با اجرای برنامه اطمینان حاصل کنیم که نصب کار می کند runserver
دستور:
❯ 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.
با باز کردن پیوند صفحه خوش آمدگویی جنگو را به ما نشان می دهد
نادیده گرفتن مدل پیشفرض احراز هویت کاربر
قبل از اجرای مهاجرت های معلق، همانطور که هنگام اجرای آن پیشنهاد شد runserver
با دستور، مدل کاربر پیشفرض جنگو را لغو میکنیم، که بهترین روش برای پروژههای جدید است. ادبیات زیادی در مورد اینکه چرا این ایده خوب است، از جمله مستندات رسمی وجود دارد.
بعداً ممکن است بخواهیم ترکیب کنیم django-allauth
در پروژه، اما ما میخواهیم آن را ساده نگه داریم و به زودی چیزی راهاندازی کنیم، بنابراین بیایید یک برنامه به نام ایجاد کنیم core
، ایجاد یک UserProfile
کلاس ارث بردن از AbstractUser
و پروژه ما را طوری تنظیم کنیم که از این کلاس به عنوان مدل احراز هویت استفاده کند.
❯ uv run python manage.py startapp core
بیایید مدل را اضافه کنیم core/models.py
:
from django.contrib.auth.models import AbstractUser
class UserProfile(AbstractUser):
pass
در settings.py
، بیایید برنامه جدید خود را اضافه کنیم و مدل کاربر احراز هویت را تغییر دهیم:
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
اکنون میتوانیم مهاجرتها را انجام دهیم، آنها را اعمال کنیم و یک ابرکاربر برای برنامه ایجاد کنیم:
❯ 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: admin@email.com
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.
❯
اجرای مجدد برنامه با runserver
و باز کردن localhost:8000/admin
صفحه مدیریت جنگو را به ما نشان می دهد:
برای تکمیل قسمت 1، میتوانیم یک نمای مدیریتی برای آن ثبت کنیم 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']
به روز رسانی سایت مدیریت، رابط مدیریت را برای کاربران به ما نشان می دهد
این برای راه اندازی اولیه پروژه ما تمام شد! در قسمت 2، ما از TDD برای پیاده سازی اولین نسخه از مدل Todo استفاده می کنیم و زمانی که کد را به Github فشار می دهیم، یک اکشن Github را برای اجرای تست های واحد تنظیم می کنیم.