ایجاد دستور (کامند) برای بارگذاری خودکار Fixturesهای کل پروژه در جنگو Django

ایجاد دستور (کامند) برای بارگذاری خودکار Fixturesهای کل پروژه در جنگو Django
ایجاد دستور (کامند) برای بارگذاری خودکار Fixturesهای کل پروژه در جنگو Django

ایجاد دستور (کامند) برای بارگذاری خودکار Fixturesهای کل پروژه در جنگو Django

در پروژه‌های جنگو Django، هنگام توسعه‌ی پروژه، معمولا نیاز داریم که داده‌های اولیه (fixtures) را در دیتابیس یا بانک اطلاعاتی بارگذاری کنیم. این کار به ما کمک می‌کند که بدون ورود دستی داده‌ها، محیط توسعه را سریع‌تر برای استفاده آماده کنیم. در این نوشته، قصد داریم یک دستور مدیریت سفارشی یا کامند (Management Command) ایجاد کنیم که تمام فایل‌های fixture را از اپلیکیشن‌های مختلف پروژه به‌صورت خودکار همه را یکجا بارگذاری کند.

 

ایجاد دستور (کامند) برای بارگذاری خودکار Fixturesهای کل پروژه در جنگو Django

ایجاد دستور مدیریت سفارشی برای بارگذاری خودکار Fixtures

ایجاد یک فایل Command در پروژه: درون یکی از اپلیکیشن‌های خود، مسیر زیر را ایجاد کنید:

your_app/
│── management/
│   ├── commands/
│   │   ├── __init__.py
│   │   ├── load_all_fixtures.py  <-- فایل جدید ما

در فایل load_all_fixtures.py، کد زیر را قرار دهید:

import os
from django.conf import settings
from django.core.management import call_command
from django.core.management.base import BaseCommand

class Command(BaseCommand):
    help = "Loads all fixtures automatically in dependency order"

    def handle(self, *args, **options):
        APP_MODE = settings.APP_MODE
        if APP_MODE != "development":
            self.stdout.write(
                self.style.WARNING("This command is intended for development mode.")
            )
            return

        local_apps = getattr(settings, "LOCAL_APPS", [])

        if not local_apps:
            self.stdout.write(self.style.ERROR("No LOCAL_APPS found in settings.py."))
            return

        fixtures_map = {}

        for app_label in local_apps:
            fixtures_dir = os.path.join(app_label.replace(".", "/"), "fixtures")
            if os.path.exists(fixtures_dir):
                fixtures = [
                    os.path.join(fixtures_dir, f)
                    for f in os.listdir(fixtures_dir)
                    if f.endswith(".json")
                ]
                fixtures_map[app_label] = fixtures

        if not fixtures_map:
            self.stdout.write(self.style.WARNING("No fixtures found in any app."))
            return

        loaded_fixtures = set()

        def load_fixture(fixture_path):
            try:
                self.stdout.write(f"Loading {fixture_path}")
                call_command("loaddata", fixture_path)
                loaded_fixtures.add(fixture_path)
                return True
            except Exception as e:
                self.stdout.write(
                    self.style.WARNING(
                        f"Retrying later: {fixture_path} due to error: {e}"
                    )
                )
                return False

        all_fixtures = [fp for fixtures in fixtures_map.values() for fp in fixtures]
        while all_fixtures:
            remaining_fixtures = []
            for fixture_path in all_fixtures:
                if not load_fixture(fixture_path):
                    remaining_fixtures.append(fixture_path)
            if len(remaining_fixtures) == len(all_fixtures):
                break
            all_fixtures = remaining_fixtures

        if all_fixtures:
            self.stdout.write(
                self.style.ERROR(
                    "The following fixtures could not be loaded due to errors:"
                )
            )
            for fixture_path in all_fixtures:
                self.stdout.write(self.style.ERROR(f" - {fixture_path}"))
        else:
            self.stdout.write(self.style.SUCCESS("All fixtures loaded successfully."))

 

توضیح عملکرد کد

این دستور چه کار می‌کند؟

  • بررسی می‌کند که APP_MODE در تنظیمات پروژه برابر development باشد. اگر نباشد، دستور اجرا نخواهد شد.
  • لیست اپلیکیشن‌های محلی (LOCAL_APPS) را از فایل تنظیمات (settings.py) دریافت می‌کند.
  • در هر اپلیکیشن، پوشه fixtures را جستجو می‌کند و فایل‌های .json را پیدا می‌کند.
  • تلاش می‌کند تا تمام fixtures پروژه را بارگذاری کند.
  • اگر بارگذاری یک فایل به خطا بخورد، آن را در انتها دوباره تلاش می‌کند.
  • در نهایت، اگر برخی از فایل‌ها بارگذاری نشوند، لیست آن‌ها را نمایش می‌دهد.

 

استفاده از این دستور در پروژه: برای اجرای این دستور، کافی است در ترمینال خود دستور زیر را اجرا کنید:

python manage.py load_all_fixtures

اگر همه چیز درست باشد، خروجی مشابه زیر خواهید دید:

Loading my_app/fixtures/sample_data.json

All fixtures loaded successfully.

اگر برخی از فایل‌ها خطا داشته باشند، به شما اطلاع داده خواهد شد تا مشکل را بررسی کنید.

 

این دستور به شما کمک می‌کند که داده‌های اولیه را در محیط توسعه به‌راحتی بارگذاری کنید. همچنین، در صورت بروز خطا، آن را مدیریت کرده و تلاش مجدد انجام می‌دهد. با استفاده از این روش، دیگر نیازی نیست که هر بار به صورت دستی loaddata را برای هر اپلیکیشن اجرا کنید!

برای امتیاز به این نوشته کلیک کنید!
[کل: 2 میانگین: 5]