برنامه نویسی

ایجاد یک برنامه 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 را برای اجرای تست های واحد تنظیم می کنیم.

نوشته های مشابه

دیدگاهتان را بنویسید

نشانی ایمیل شما منتشر نخواهد شد. بخش‌های موردنیاز علامت‌گذاری شده‌اند *

دکمه بازگشت به بالا