لیست ۲۵ خطای پرتکرار جنگو و روش رفع آن، مرجعی است که هر توسعه‌دهنده Django در طول کار خود به آن نیاز پیدا می‌کند. جنگو به‌عنوان یک فریم‌ورک قدرتمند، خطاهای بسیار دقیق و معناداری تولید می‌کند، اما همین دقت گاهی باعث سردرگمی می‌شود. در این راهنما، ۲۵ خطای رایج را از خطاهای نصب و پیکربندی تا خطاهای ORM، Template و Migration با علت ریشه‌ای، روش عیب‌یابی، راه‌حل عملی و روش تأیید رفع، به‌صورت فشرده اما کامل بررسی می‌کنیم. هدف این است که با خواندن این مقاله، بتوانید در کمترین زمان ریشه خطا را پیدا کنید و بدون آزمون‌وخطا آن را برطرف کنید.

در تجربه کار با پروژه‌های متعدد جنگو، الگویی تکرارشونده دیده‌ام: توسعه‌دهندگان معمولاً با پیام خطا سر و کله می‌زنند، نه با ریشه آن. اما اگر بدانید هر خطا از کدام لایه معماری می‌آید، سرعت عیب‌یابی چند برابر می‌شود. این مقاله دقیقاً همین کار را می‌کند.

چرا خطاهای جنگو در نگاه اول گیج‌کننده به نظر می‌رسند؟

جنگو خطاها را در چند لایه تولید می‌کند: لایه Python (ImportError، ModuleNotFoundError)، لایه پیکربندی (ImproperlyConfigured)، لایه ORM (FieldError، IntegrityError)، لایه دیتابیس (OperationalError، ProgrammingError)، لایه Template (TemplateDoesNotExist)، لایه URL (NoReverseMatch) و لایه امنیتی (DisallowedHost، CSRF). هر لایه پیام‌های خاص خود را دارد و ریشه خطا معمولاً در همان لایه‌ای است که پیام از آن می‌آید، نه در لایه‌ای که خطا در آن دیده می‌شود.

نکته کلیدی این است که جنگو در حالت DEBUG=True، خطای کاملی با Traceback، Local Variables و Settings نمایش می‌دهد. اولین کار در مواجهه با هر خطا، فعال کردن حالت DEBUG در محیط توسعه است. در محیط تولید، DEBUG باید False باشد، اما برای عیب‌یابی می‌توانید از ابزارهایی مانند Sentry یا لاگ‌های سرور استفاده کنید. اگر با لاگ‌های سرور آشنایی ندارید، فایل stderr.log چیست و چه کاربردی دارد؟ را مطالعه کنید.

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

خطاهای ۱ تا ۵: نصب، پیکربندی و راه‌اندازی

خطای ۱: ModuleNotFoundError: No module named 'django'

علائم: به‌محض اجرای python manage.py runserver یا هر دستور دیگر، Python نمی‌تواند ماژول django را پیدا کند.

علت ریشه‌ای: جنگو در محیط فعلی Python نصب نیست، یا محیط مجازی (Virtual Environment) فعال نشده است، یا pip به نسخه دیگری از Python اشاره می‌کند.

عیب‌یابی: ابتدا بررسی کنید که در کدام محیط Python هستید:

which python
which pip
pip list | grep -i django

در ویندوز از where python استفاده کنید. اگر django در لیست نبود، نصب نشده است. اگر نصب شده اما Python آن را پیدا نمی‌کند، محیط مجازی فعال نیست.

راه‌حل: محیط مجازی را فعال کنید و جنگو را نصب کنید:

python -m venv venv
source venv/bin/activate   # لینوکس و مک
venv\Scripts\activate      # ویندوز
pip install django

برای راهنمای کامل pip در جنگو، دستورات pip در جنگو: راهنمای کامل را ببینید.

تأیید: python -c "import django; print(django.get_version())" باید نسخه را نمایش دهد.

پیشگیری: همیشه از محیط مجازی مجزا برای هر پروژه استفاده کنید و فایل requirements.txt را به‌روز نگه دارید.

خطای ۲: ImportError: cannot import name 'X' from 'module'

علائم: هنگام import یک کلاس، تابع یا ماژول، پیام می‌دهد که نام موردنظر در آن ماژول وجود ندارد.

علت ریشه‌ای: معمولاً به سه دلیل رخ می‌دهد: (۱) نام اشتباه تایپ شده، (۲) circular import (import دوری)، (۳) نسخه کتابخانه با کد شما سازگار نیست.

عیب‌یابی: مسیر خطا را در Traceback دنبال کنید. اگر circular import است، خطا معمولاً در فایل‌هایی رخ می‌دهد که به هم ارجاع می‌دهند. برای بررسی نسخه:

pip show package-name

راه‌حل: اگر circular import است، import را به داخل تابع منتقل کنید:

# به‌جای import در بالای فایل
from myapp.models import MyModel

def my_view(request):
    from myapp.models import MyModel  # import داخل تابع
    obj = MyModel.objects.first()

اگر نسخه ناسازگار است، نسخه سازگار را نصب کنید:

pip install package-name==compatible-version

تأیید: اجرای مجدد سرور بدون خطا.

پیشگیری: در پروژه‌های بزرگ، از ساختار لایه‌ای (services، models، views) استفاده کنید تا circular import رخ ندهد. مقاله services.py در جنگو: چرا منطق کسب‌وکار باید از ویو جدا شود؟ راهنمای مفیدی است.

خطای ۳: ImproperlyConfigured: The SECRET_KEY setting must not be empty

علائم: هنگام اجرای سرور، جنگو پیام می‌دهد که SECRET_KEY خالی است.

علت ریشه‌ای: متغیر SECRET_KEY در فایل settings.py تعریف نشده یا از فایل .env خوانده نشده است.

عیب‌یابی: فایل settings.py را باز کنید و وجود خط SECRET_KEY = ... را بررسی کنید. اگر از django-environ استفاده می‌کنید، مطمئن شوید فایل .env در مسیر درست قرار دارد.

راه‌حل: یک SECRET_KEY جدید تولید کنید و در فایل تنظیمات قرار دهید:

python -c "from django.core.management.utils import get_random_secret_key; print(get_random_secret_key())"

سپس در settings.py:

SECRET_KEY = 'your-generated-secret-key'

تأیید: سرور بدون خطا اجرا می‌شود.

پیشگیری: SECRET_KEY را در مخزن گیت قرار ندهید. از فایل .env استفاده کنید و آن را در .gitignore قرار دهید. برای امنیت بیشتر، امنیت در Django: بهترین روش‌ها را ببینید.

خطای ۴: ImproperlyConfigured: settings.DATABASES is improperly configured

علائم: هنگام اجرای migrate یا هر دستور دیتابیس، جنگو پیام می‌دهد که تنظیمات دیتابیس ناقص است.

علت ریشه‌ای: کلید NAME، USER، PASSWORD یا HOST در دیکشنری DATABASES خالی یا اشتباه است، یا درایور دیتابیس نصب نیست.

عیب‌یابی: بخش DATABASES را در settings.py بررسی کنید. مطمئن شوید ENGINE با دیتابیس انتخابی مطابقت دارد.

DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.postgresql',
        'NAME': 'mydb',
        'USER': 'myuser',
        'PASSWORD': 'mypassword',
        'HOST': 'localhost',
        'PORT': '5432',
    }
}

راه‌حل: درایور مناسب را نصب کنید. برای PostgreSQL:

pip install psycopg2-binary

برای MySQL:

pip install mysqlclient

تأیید: python manage.py migrate بدون خطا اجرا می‌شود.

پیشگیری: مقادیر حساس را از .env بخوانید و در settings.py استفاده کنید.

خطای ۵: django.core.exceptions.ImproperlyConfigured: Requested setting INSTALLED_APPS, but settings are not configured

علائم: هنگام اجرای یک اسکریپت Python خارج از manage.py، خطا رخ می‌دهد.

علت ریشه‌ای: اسکریپت شما به تنظیمات جنگو دسترسی ندارد، زیرا DJANGO_SETTINGS_MODULE تنظیم نشده است.

عیب‌یابی: مطمئن شوید اسکریپت را با manage.py shell اجرا می‌کنید یا متغیر محیطی را تنظیم کرده‌اید.

راه‌حل: در ابتدای اسکریپت، تنظیمات را بارگذاری کنید:

import os
import django

os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'myproject.settings')
django.setup()

# حالا می‌توانید مدل‌ها را import کنید
from myapp.models import MyModel

تأیید: اسکریپت بدون خطا اجرا می‌شود.

پیشگیری: برای اسکریپت‌های مستقل، از django.setup() استفاده کنید یا آن‌ها را به‌عنوان کامند مدیریتی سفارشی بنویسید.

خطاهای ۶ تا ۱۰: دیتابیس و Migration

خطای ۶: django.db.utils.OperationalError: no such table: app_model

علائم: هنگام اجرای کوئری روی مدل، پیام می‌دهد جدول موردنظر وجود ندارد.

علت ریشه‌ای: Migration‌ها اعمال نشده‌اند، یا نام جدول با نام مدل مطابقت ندارد.

عیب‌یابی: وضعیت Migration‌ها را بررسی کنید:

python manage.py showmigrations

اگر علامت [ ] در کنار یک Migration است، هنوز اعمال نشده.

راه‌حل: Migration‌ها را بسازید و اعمال کنید:

python manage.py makemigrations
python manage.py migrate

برای خطاهای دقیق‌تر Migration، چگونه خطاهای رایج Django را سریع و اصولی رفع کنیم؟ را ببینید.

تأیید: python manage.py showmigrations همه Migration‌ها را با [X] نشان می‌دهد.

پیشگیری: پس از هر تغییر مدل، بلافاصله makemigrations و migrate را اجرا کنید.

خطای ۷: OperationalError: unable to open database file (SQLite)

علائم: هنگام اجرای migrate، جنگو پیام می‌دهد که نمی‌تواند فایل دیتابیس SQLite را باز کند.

علت ریشه‌ای: مسیر فایل SQLite اشتباه است، پوشه والد وجود ندارد، یا مجوز نوشتن وجود ندارد.

عیب‌یابی: مسیر کامل فایل را بررسی کنید:

ls -la db.sqlite3
ls -la /path/to/db.sqlite3

راه‌حل: مسیر مطلق صحیح را در settings.py تنظیم کنید:

import os
BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.sqlite3',
        'NAME': os.path.join(BASE_DIR, 'db.sqlite3'),
    }
}

مجوز پوشه را بررسی کنید:

chmod 755 /path/to/project

تأیید: migrate بدون خطا اجرا می‌شود و فایل db.sqlite3 ایجاد می‌شود.

پیشگیری: از مسیرهای مطلق استفاده کنید و پروژه را در مسیرهایی با مجوز نوشتن قرار دهید.

خطای ۸: OperationalError: FATAL: password authentication failed for user

علائم: هنگام اتصال به PostgreSQL، جنگو پیام می‌دهد که رمز عبور نامعتبر است.

علت ریشه‌ای: رمز عبور کاربر دیتابیس اشتباه است، یا متد احراز هویت pg_hba.conf نامناسب است.

عیب‌یابی: با psql تلاش کنید:

psql -h localhost -U myuser -d mydb

اگر خطا داد، مشکل در رمز یا مجوزهاست.

راه‌حل: رمز را در PostgreSQL بازنشانی کنید:

sudo -u postgres psql
ALTER USER myuser WITH PASSWORD 'newpassword';

سپس settings.py را به‌روز کنید.

تأیید: migrate بدون خطا اجرا می‌شود.

پیشگیری: رمز را در .env نگهداری کنید و از ذخیره رمز در مخزن گیت خودداری کنید.

خطای ۹: ProgrammingError: relation "app_model" does not exist

علائم: مشابه خطای no such table، اما در PostgreSQL.

علت ریشه‌ای: Migration‌ها اعمال نشده یا جدول در schema اشتباه ایجاد شده است.

عیب‌یابی: schema فعلی را بررسی کنید:

python manage.py dbshell
\dt

راه‌حل: Migration‌ها را اعمال کنید:

python manage.py migrate

اگر schema مشکل دارد:

DATABASES['default']['OPTIONS'] = {'options': '-c search_path=myschema'}

تأیید: کوئری‌ها بدون خطا اجرا می‌شوند.

پیشگیری: در پروژه‌های multi-tenant، از django-tenants استفاده کنید و Migration‌ها را با migrate_schemas اجرا کنید.

خطای ۱۰: django.db.migrations.exceptions.NodeNotFoundError

علائم: هنگام اجرای migrate، جنگو پیام می‌دهد که Migration والد پیدا نشد.

علت ریشه‌ای: یک Migration حذف شده یا بین شاخه‌ها ناسازگاری وجود دارد.

عیب‌یابی: لیست Migration‌ها را بررسی کنید:

python manage.py showmigrations myapp

راه‌حل: Migration گمشده را بازگردانید یا با squash یکپارچه کنید:

python manage.py squashmigrations myapp 0001 0010

تأیید: migrate بدون خطا اجرا می‌شود.

پیشگیری: هرگز Migration‌های اعمال‌شده را حذف نکنید. برای بازنشانی، از دستور migrate myapp zero استفاده کنید و سپس دوباره migrate کنید.

خطاهای ۱۱ تا ۱۵: ORM و مدل‌ها

خطای ۱۱: django.db.utils.IntegrityError: UNIQUE constraint failed

علائم: هنگام ذخیره یک شیء، پیام می‌دهد که مقدار تکراری است.

علت ریشه‌ای: یک فیلد با unique=True قرار است مقدار تکراری بگیرد.

عیب‌یابی: نام فیلد را در پیام خطا ببینید و بررسی کنید کدام مقدار تکراری است:

MyModel.objects.filter(email='test@example.com').exists()

راه‌حل: از get_or_create یا update_or_create استفاده کنید:

obj, created = MyModel.objects.get_or_create(
    email='test@example.com',
    defaults={'name': 'Ali'}
)

یا خطا را در view مدیریت کنید:

from django.db import IntegrityError
try:
    obj.save()
except IntegrityError:
    # مدیریت تکراری بودن
    pass

تأیید: ذخیره بدون خطا انجام می‌شود.

پیشگیری: قبل از ذخیره، وجود رکورد را بررسی کنید.

خطای ۱۲: IntegrityError: NOT NULL constraint failed

علائم: هنگام ذخیره، پیام می‌دهد که یک فیلد نمی‌تواند NULL باشد.

علت ریشه‌ای: فیلدی که null=False دارد، مقدار None گرفته است.

عیب‌یابی: نام فیلد را در پیام ببینید و مقدار آن را بررسی کنید.

راه‌حل: مقدار پیش‌فرض تعریف کنید:

name = models.CharField(max_length=100, default='')

یا در فرم، فیلد را اجباری کنید.

تأیید: ذخیره بدون خطا انجام می‌شود.

پیشگیری: در مدل‌ها، مقادیر پیش‌فرض منطقی تعریف کنید.

خطای ۱۳: IntegrityError: FOREIGN KEY constraint failed

علائم: هنگام ذخیره، پیام می‌دهد که کلید خارجی نامعتبر است.

علت ریشه‌ای: شیء مرتبط وجود ندارد یا حذف شده است.

عیب‌یابی: مقدار کلید خارجی را بررسی کنید:

Author.objects.filter(id=author_id).exists()

راه‌حل: ابتدا شیء مرتبط را بسازید یا از on_delete=models.SET_NULL استفاده کنید:

author = models.ForeignKey(Author, on_delete=models.SET_NULL, null=True)

تأیید: ذخیره بدون خطا انجام می‌شود.

پیشگیری: از on_delete مناسب استفاده کنید و روابط را در فرم‌ها اعتبارسنجی کنید.

خطای ۱۴: FieldError: Cannot resolve keyword 'X' into field

علائم: هنگام filter یا order_by، پیام می‌دهد که فیلد وجود ندارد.

علت ریشه‌ای: نام فیلد اشتباه است یا در مدل تعریف نشده.

عیب‌یابی: فیلدهای مدل را بررسی کنید:

[f.name for f in MyModel._meta.get_fields()]

راه‌حل: نام صحیح فیلد را استفاده کنید. اگر فیلد مرتبط است، از related_field__sub_field استفاده کنید:

MyModel.objects.filter(author__name='Ali')

تأیید: کوئری بدون خطا اجرا می‌شود.

پیشگیری: نام فیلدها را قبل از کوئری بررسی کنید.

خطای ۱۵: MyModel.DoesNotExist یا MultipleObjectsReturned

علائم: هنگام استفاده از get()، پیام می‌دهد که شیء پیدا نشد یا چند شیء برگشت.

علت ریشه‌ای: get() فقط زمانی کار می‌کند که دقیقاً یک رکورد مطابق فیلتر باشد.

عیب‌یابی: تعداد رکوردها را بررسی کنید:

MyModel.objects.filter(email='test@example.com').count()

راه‌حل: از filter().first() استفاده کنید یا خطا را مدیریت کنید:

try:
    obj = MyModel.objects.get(email='test@example.com')
except MyModel.DoesNotExist:
    obj = None
except MyModel.MultipleObjectsReturned:
    obj = MyModel.objects.filter(email='test@example.com').first()

یا از get_object_or_404 در view استفاده کنید.

تأیید: view بدون خطا پاسخ می‌دهد.

پیشگیری: از get() فقط زمانی استفاده کنید که یکتایی تضمین شده باشد.

خطاهای ۱۶ تا ۲۰: Template و URL

خطای ۱۶: TemplateDoesNotExist

علائم: هنگام رندر یک view، پیام می‌دهد که قالب پیدا نشد.

علت ریشه‌ای: مسیر قالب اشتباه است یا TEMPLATES در settings.py به پوشه درست اشاره نمی‌کند.

عیب‌یابی: مسیر قالب‌ها را بررسی کنید:

import os
print(os.listdir('myapp/templates'))

راه‌حل: قالب را در مسیر درست قرار دهید و APP_DIRS را فعال کنید:

TEMPLATES = [
    {
        'BACKEND': 'django.template.backends.django.DjangoTemplates',
        'DIRS': [BASE_DIR / 'templates'],
        'APP_DIRS': True,
    },
]

تأیید: view بدون خطا رندر می‌شود.

پیشگیری: ساختار پوشه templates را استاندارد نگه دارید: app/templates/app/template.html.

خطای ۱۷: TemplateSyntaxError: Invalid block tag

علائم: هنگام رندر قالب، پیام می‌دهد که تگ نامعتبر است.

علت ریشه‌ای: تگ یا فیلتر در قالب اشتباه تایپ شده یا در {% load %} بارگذاری نشده است.

عیب‌یابی: خطای Traceback شماره خط را نشان می‌دهد.

راه‌حل: تگ را بررسی کنید و در صورت نیاز {% load %} اضافه کنید:

{% load static %}
<link rel="stylesheet" href="{% static 'style.css' %}">

تأیید: قالب بدون خطا رندر می‌شود.

پیشگیری: قالب‌ها را در ادیتور با هایلایت سینتکس بنویسید.

خطای ۱۸: NoReverseMatch: Reverse for 'name' not found

علائم: هنگام استفاده از {% url %} یا reverse()، پیام می‌دهد که نام URL پیدا نشد.

علت ریشه‌ای: نام URL اشتباه است، پارامتر اجباری داده نشده، یا namespace اشتباه است.

عیب‌یابی: لیست URL name‌ها را بررسی کنید:

python manage.py show_urls

یا در shell:

from django.urls import get_resolver
print(get_resolver().reverse_dict.keys())

راه‌حل: نام صحیح و پارامترها را وارد کنید:

{% url 'post-detail' pk=post.id %}

اگر namespace دارد:

{% url 'blog:post-detail' pk=post.id %}

تأیید: صفحه بدون خطا رندر می‌شود.

پیشگیری: از name معنادار برای URLها استفاده کنید و آن‌ها را در یک فایل ثابت نگه دارید.

خطای ۱۹: DisallowedHost: Invalid HTTP_HOST header

علائم: با بازدید سایت، پیام می‌دهد که دامنه مجاز نیست.

علت ریشه‌ای: دامنه در ALLOWED_HOSTS تعریف نشده است.

عیب‌یابی: دامنه درخواست را در پیام ببینید.

راه‌حل: دامنه را اضافه کنید:

ALLOWED_HOSTS = ['example.com', 'www.example.com', 'localhost', '127.0.0.1']

برای محیط توسعه:

ALLOWED_HOSTS = ['*']

اما هرگز در تولید از * استفاده نکنید.

تأیید: سایت بدون خطا بارگذاری می‌شود.

پیشگیری: دامنه‌ها را از متغیر محیطی بخوانید.

خطای ۲۰: CSRF verification failed

علائم: هنگام ارسال فرم، پیام می‌دهد که CSRF token نامعتبر است.

علت ریشه‌ای: فرم فاقد {% csrf_token %} است، یا کوکی CSRF تنظیم نشده، یا دامنه اشتباه است.

عیب‌یابی: فرم را بررسی کنید و مطمئن شوید {% csrf_token %} داخل <form> قرار دارد.

راه‌حل: تگ را اضافه کنید:

<form method="post">
    {% csrf_token %}
    <input type="text" name="name">
    <button type="submit">Submit</button>
</form>

اگر API است و CSRF نمی‌خواهید، از @csrf_exempt استفاده کنید (با احتیاط):

from django.views.decorators.csrf import csrf_exempt

@csrf_exempt
def my_api_view(request):
    pass

تأیید: فرم بدون خطا ارسال می‌شود.

پیشگیری: همیشه CSRF را فعال نگه دارید مگر برای APIهای احراز هویت‌شده با Token. برای امنیت بیشتر، چگونه نانس را در فرم‌های سفارشی وردپرس درست پیاده‌سازی کنیم؟ را ببینید که مفاهیم مشابهی دارد.

خطاهای ۲۱ تا ۲۵: امنیت، CSRF و Runtime

خطای ۲۱: PermissionError: [Errno 13] Permission denied

علائم: هنگام نوشتن در فایل یا پوشه، خطای مجوز رخ می‌دهد.

علت ریشه‌ای: کاربر اجراکننده جنگو مجوز نوشتن در مسیر موردنظر را ندارد.

عیب‌یابی: مجوز مسیر را بررسی کنید:

ls -la /path/to/directory
whoami

راه‌حل: مجوز مناسب را اعمال کنید:

sudo chown -R www-data:www-data /path/to/directory
sudo chmod -R 755 /path/to/directory

برای فایل‌های حساس مانند .env:

chmod 640 .env

تأیید: عملیات نوشتن بدون خطا انجام می‌شود.

پیشگیری: کاربر اجراکننده جنگو باید مالک پوشه‌های media و static باشد.

خطای ۲۲: SuspiciousFileOperation

علائم: هنگام آپلود فایل، پیام می‌دهد که عملیات مشکوک است.

علت ریشه‌ای: مسیر فایل از MEDIA_ROOT خارج می‌شود یا شامل کاراکترهای مشکوک است.

عیب‌یابی: مسیر فایل آپلودشده را بررسی کنید.

راه‌حل: نام فایل را پاک‌سازی کنید:

import os
from django.utils.text import get_valid_filename

filename = get_valid_filename(request.FILES['file'].name)

یا از FileSystemStorage سفارشی استفاده کنید.

تأیید: آپلود بدون خطا انجام می‌شود.

پیشگیری: همیشه نام فایل‌های آپلودی را اعتبارسنجی کنید.

خطای ۲۳: RuntimeError: Model class doesn't declare an explicit app_label

علائم: هنگام import یک مدل، پیام می‌دهد که مدل app_label ندارد.

علت ریشه‌ای: مدل در یک اپ ثبت‌نشده تعریف شده، یا import آن در جای اشتباه انجام شده.

عیب‌یابی: INSTALLED_APPS را بررسی کنید و مطمئن شوید اپ مدل در آن هست.

راه‌حل: اپ را به INSTALLED_APPS اضافه کنید:

INSTALLED_APPS = [
    ...
    'myapp',
]

اگر circular import است، import را به داخل تابع منتقل کنید.

تأیید: مدل بدون خطا import می‌شود.

پیشگیری: ساختار اپ‌ها را از ابتدا درست طراحی کنید.

خطای ۲۴: AppRegistryNotReady: Apps aren't loaded yet

علائم: هنگام import یک مدل قبل از django.setup()، خطا رخ می‌دهد.

علت ریشه‌ای: مدل قبل از بارگذاری اپ‌ها import شده است.

عیب‌یابی: ترتیب import‌ها را بررسی کنید.

راه‌حل: در اسکریپت‌ها، ابتدا django.setup() را فراخوانی کنید:

import django
django.setup()
from myapp.models import MyModel

در apps.py، از ready() برای import مدل استفاده کنید، نه در بالای فایل.

تأیید: اسکریپت بدون خطا اجرا می‌شود.

پیشگیری: همیشه ترتیب import و setup را رعایت کنید.

خطای ۲۵: django.db.utils.OperationalError: database is locked (SQLite)

علائم: در محیط توسعه با SQLite، هنگام نوشتن همزمان، خطای قفل دیتابیس رخ می‌دهد.

علت ریشه‌ای: SQLite از قفل‌گذاری فایل استفاده می‌کند و نوشتن همزمان را پشتیبانی نمی‌کند.

عیب‌یابی: بررسی کنید آیا پروسه‌های همزمان روی دیتابیس کار می‌کنند.

راه‌حل: timeout را افزایش دهید:

DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.sqlite3',
        'NAME': BASE_DIR / 'db.sqlite3',
        'OPTIONS': {'timeout': 20},
    }
}

یا به PostgreSQL مهاجرت کنید.

تأیید: عملیات همزمان بدون خطا انجام می‌شود.

پیشگیری: برای پروژه‌های تولیدی، از PostgreSQL یا MySQL استفاده کنید. برای بهینه‌سازی، بهینه‌سازی عملکرد جنگو برای سایت پربازدید را ببینید.

گردش‌کار حرفه‌ای عیب‌یابی خطاهای جنگو

برای عیب‌یابی مؤثر، یک گردش‌کار ساختاریافته را دنبال کنید:

  1. خواندن کامل Traceback: آخرین خط، نوع خطا را نشان می‌دهد. خطوط قبلی مسیر رخداد را.
  2. شناسایی لایه: Python، Django، ORM، Template، URL یا Database؟
  3. بازتولید در محیط ایزوله: خطا را در shell یا یک تست واحد بازتولید کنید.
  4. بررسی تغییرات اخیر: از git diff برای دیدن تغییرات پس از آخرین وضعیت پایدار استفاده کنید.
  5. جستجو در مستندات رسمی: Django Docs مرجع اصلی است.
  6. اعمال حداقل تغییر: یک تغییر کوچک اعمال کنید و نتیجه را بررسی کنید.
  7. تأیید رفع: خطا نباید تکرار شود و رفتار سیستم باید پایدار بماند.

ابزارهایی مانند رفع خطاهای رایج Django و چرا وردپرس خطا نشان می‌دهد و رفع با Debug می‌توانند در این مسیر کمک کنند.

پرسش‌های پرتکرار درباره خطاهای جنگو

چگونه خطاهای جنگو را در تولید لاگ کنم؟

در settings.py بخش LOGGING را پیکربندی کنید و لاگ‌ها را به فایل یا سرویس جمع‌آوری لاگ بفرستید. برای سرور، فایل stderr.log چیست و چه کاربردی دارد؟ را ببینید.

تفاوت DEBUG=True و DEBUG=False چیست؟

در حالت DEBUG=True، جنگو Traceback کامل با متغیرها و تنظیمات نمایش می‌دهد. در DEBUG=False، یک صفحه 500 ساده نمایش داده می‌شود و جزئیات در لاگ ثبت می‌شود. برای عیب‌یابی از DEBUG=True و در تولید از DEBUG=False استفاده کنید.

چرا خطای no such table بعد از migrate همچنان رخ می‌دهد؟

ممکن است Migration‌ها در دیتابیس اشتباه اعمال شده باشند یا --fake استفاده شده باشد. python manage.py showmigrations وضعیت را نشان می‌دهد.

چگونه خطای circular import را رفع کنم؟

import‌ها را به داخل توابع منتقل کنید یا از django.apps.apps.get_model() برای import تأخیری استفاده کنید.

چرا خطای CSRF در API رخ می‌دهد؟

برای APIهای بدون حالت (stateless)، از Token Authentication یا JWT استفاده کنید. اگر نمی‌خواهید CSRF داشته باشید، از @csrf_exempt استفاده کنید اما با احتیاط.

چگونه خطای IntegrityError را در فرم‌ها مدیریت کنم؟

در form_valid یا save، از try/except IntegrityError استفاده کنید و پیام مناسب نمایش دهید.

چرا خطای MultipleObjectsReturned رخ می‌دهد؟

زمانی که get() بیش از یک رکورد مطابق پیدا کند. از filter().first() استفاده کنید یا یکتایی را تضمین کنید.

چگونه خطاهای Template را سریع‌تر پیدا کنم؟

از django-template-check یا ابزارهای IDE برای بررسی قالب‌ها استفاده کنید. همچنین در حالت DEBUG، شماره خط و مسیر قالب نمایش داده می‌شود.

چرا DisallowedHost در تولید رخ می‌دهد؟

دامنه در ALLOWED_HOSTS نیست. دامنه صحیح را اضافه کنید و از * در تولید خودداری کنید.

چگونه خطاهای Migration را بازنشانی کنم؟

اگر پروژه در حالت توسعه است، می‌توانید Migration‌ها را حذف کنید و دیتابیس را از نو بسازید. در تولید، از migrate app zero یا squash استفاده کنید.

ملاحظات سطح ارشد

در سطح مهندسی ارشد، مدیریت خطاها بخشی از استراتژی Observability است. خطاها نباید فقط رفع شوند؛ باید ثبت، دسته‌بندی و برای پیشگیری استفاده شوند. ابزارهایی مانند Sentry، Rollbar و Elastic APM می‌توانند خطاها را در محیط تولید ثبت و دسته‌بندی کنند.

نکته کمتر شناخته‌شده: جنگو در حالت DEBUG، خطاها را در حافظه نگه می‌دارد. برای پروژه‌های بزرگ، می‌توانید از django-debug-toolbar برای تحلیل دقیق کوئری‌ها و زمان اجرا استفاده کنید. اما هرگز آن را در تولید فعال نکنید.

در معماری میکروسرویس، خطاها باید با Trace ID مرتبط شوند تا ردیابی درخواست در سرویس‌های مختلف ممکن باشد. OpenTelemetry استاندارد فعلی برای این کار است. برای آشنایی با معماری وب مدرن، اصول طراحی معماری وب مدرن را ببینید.

یک الگوی پیشرفته دیگر، استفاده از Circuit Breaker برای مدیریت خطاهای سرویس‌های خارجی است. کتابخانه‌هایی مانند pybreaker و tenacity در پایتون این الگو را پیاده‌سازی می‌کنند. برای بهینه‌سازی عملکرد جنگو در محیط تولید، بهینه‌سازی عملکرد جنگو برای سایت پربازدید را مطالعه کنید.

در نهایت، یکی از بهترین شیوه‌های سطح ارشد، نوشتن تست‌های خودکار برای سناریوهای خطاست. هر خطایی که در تولید رخ می‌دهد، باید به یک تست واحد یا تست یکپارچگی تبدیل شود تا در آینده جلوگیری شود. این رویکرد، خطاها را از یک رویداد تکرارشونده به یک درس دائمی تبدیل می‌کند.

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

نگاه نهایی

در این راهنما، ۲۵ خطای پرتکرار جنگو را از لایه‌های مختلف بررسی کردیم: از نصب و پیکربندی تا ORM، Template، URL و امنیت. برای هر خطا، علت ریشه‌ای، روش عیب‌یابی، راه‌حل عملی، روش تأیید و راه پیشگیری را ارائه کردیم. تسلط بر این خطاها به شما اجازه می‌دهد در پروژه‌های واقعی، سرعت عیب‌یابی را چند برابر کنید و از آزمون‌وخطا اجتناب کنید.

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