حلقه‌زدن روی فیلدهای فرم در جنگو و مدیریت فیلدهای مخفی و قابل‌مشاهده

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

BoundFieldفیلد مخفیحلقه فرم

~7 دقیقه مطالعه · آخرین به‌روزرسانی ۲۳ اسفند ۱۴۰۴

مقدمه

در بسیاری از پروژه‌های جنگو، نیاز داریم فیلدهای فرم را به صورت پویا و تکرارشونده نمایش دهیم. این کار باعث کاهش کدهای تکراری و افزایش انعطاف‌پذیری قالب‌ها می‌شود. جنگو با ارائه BoundField و متدهای کمکی، امکان کنترل کامل روی رندر فیلدها را فراهم می‌کند.


حلقه‌زدن روی فیلدهای فرم

اگر برای هر فیلد از HTML مشابهی استفاده می‌کنید، می‌توانید با یک حلقه {% for %} کدهای تکراری را حذف کنید:


{% for field in form %}
    <div class="fieldWrapper">
        {{ field.errors }}
        {{ field.label_tag }} {{ field }}
        {% if field.help_text %}
          <p class="help" id="{{ field.auto_id }}_helptext">
            {{ field.help_text|safe }}
          </p>
        {% endif %}
    </div>
{% endfor %}

ویژگی‌های مهم BoundField

هر field در حلقه یک BoundField است و ویژگی‌های مفیدی دارد:

  • field.errors: نمایش خطاهای اعتبارسنجی به صورت <ul class="errorlist">.
  • field.field: دسترسی به شیء اصلی Field و ویژگی‌هایی مانند max_length.
  • field.help_text: نمایش متن راهنما.
  • field.html_name: نام HTML فیلد.
  • field.id_for_label: شناسه HTML برای استفاده در <label>.
  • field.is_hidden: تشخیص اینکه فیلد مخفی است یا نه.
  • field.label: متن برچسب فیلد.
  • field.label_tag: برچسب HTML کامل.
  • field.legend_tag: مشابه label_tag اما با <legend>.
  • field.use_fieldset: مشخص می‌کند آیا فیلد باید داخل <fieldset> قرار گیرد.
  • field.value: مقدار فعلی فیلد.

استفاده از fieldset برای ویجت‌های چندبخشی

اگر ویجت فیلد شامل چند ورودی باشد، می‌توان آن را داخل fieldset قرار داد:


{% if field.use_fieldset %}
  <fieldset>
  {% if field.label %}{{ field.legend_tag }}{% endif %}
{% else %}
  {% if field.label %}{{ field.label_tag }}{% endif %}
{% endif %}
{{ field }}
{% if field.use_fieldset %}</fieldset>{% endif %}

حلقه‌زدن روی فیلدهای مخفی و قابل‌مشاهده

برای مدیریت جداگانه فیلدهای مخفی و قابل‌مشاهده، جنگو دو متد ارائه می‌دهد:

  • hidden_fields()
  • visible_fields()

نمونه:


{% for hidden in form.hidden_fields %}
{{ hidden }}
{% endfor %}

{% for field in form.visible_fields %}
    <div class="fieldWrapper">
        {{ field.errors }}
        {{ field.label_tag }} {{ field }}
    </div>
{% endfor %}

رندر دستی فیلدها

برای کنترل کامل روی ظاهر فیلدها، می‌توان آن‌ها را به صورت دستی رندر کرد:


{{ form.non_field_errors }}
<div class="fieldWrapper">
    {{ form.subject.errors }}
    <label for="{{ form.subject.id_for_label }}">Email subject:</label>
    {{ form.subject }}
</div>

نمایش خطاهای فرم

خطاهای هر فیلد با {{ field.errors }} نمایش داده می‌شوند:


<ul class="errorlist">
    <li>Sender is required.</li>
</ul>

برای سفارشی‌سازی بیشتر:


{% if form.subject.errors %}
    <ol>
    {% for error in form.subject.errors %}
        <li><strong>{{ error|escape }}</strong></li>
    {% endfor %}
    </ol>
{% endif %}

جمع‌بندی

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

مقدمه

جنگو از سیستم قدرتمندی برای مدیریت template engines استفاده می‌کند. این سیستم امکان استفاده از چندین موتور قالب، بارگذاری پویا، رندر قالب‌ها و مدیریت خطاهای مرتبط با قالب‌ها را فراهم می‌کند. تنظیمات مربوط به موتورهای قالب در بخش TEMPLATES قرار دارد.


پیکربندی موتورهای قالب

موتورهای قالب از طریق تنظیم TEMPLATES پیکربندی می‌شوند. این تنظیم یک لیست از دیکشنری‌هاست که هر کدام یک موتور قالب را تعریف می‌کنند:


TEMPLATES = [
    {
        "BACKEND": "django.template.backends.django.DjangoTemplates",
        "DIRS": [],
        "APP_DIRS": True,
        "OPTIONS": {
            # ...
        },
    },
]

مقدار BACKEND مسیر پایتونی کلاسی است که موتور قالب را پیاده‌سازی می‌کند. موتورهای داخلی شامل:

  • django.template.backends.django.DjangoTemplates
  • django.template.backends.jinja2.Jinja2

دو تنظیم مهم دیگر:

  • DIRS: مسیرهایی که موتور قالب باید در آن‌ها به دنبال فایل‌های قالب بگردد.
  • APP_DIRS: مشخص می‌کند آیا قالب‌ها از داخل اپلیکیشن‌ها نیز بارگذاری شوند یا نه.

بارگذاری قالب‌ها

ماژول django.template.loader دو تابع اصلی برای بارگذاری قالب‌ها ارائه می‌دهد:


تابع get_template

این تابع قالبی با نام مشخص را بارگذاری می‌کند:


from django.template.loader import get_template

template = get_template("template.html")

اگر قالب پیدا نشود، خطای TemplateDoesNotExist و اگر قالب دارای خطای نحوی باشد، خطای TemplateSyntaxError رخ می‌دهد.


بارگذاری partial

در جنگو ۶.۰ امکان بارگذاری بخش‌های خاص یک قالب با استفاده از # اضافه شده است:


partial = get_template("template.html#partial_name")

تابع select_template

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


template = select_template(["story_253_detail.html", "story_detail.html"])

مدیریت خطاهای قالب

دو استثنای مهم در هنگام بارگذاری قالب‌ها:

  • TemplateDoesNotExist: زمانی که قالب پیدا نشود.
  • TemplateSyntaxError: زمانی که قالب دارای خطای نحوی باشد.

رندر قالب‌ها

تمام قالب‌های بارگذاری‌شده دارای متد render() هستند:


template.render({"foo": "bar"})

اگر request ارسال شود، موتور قالب باید آن را در دسترس قرار دهد.


مثال الگوریتم جستجوی قالب

فرض کنید تنظیمات زیر را داریم:


TEMPLATES = [
    {
        "BACKEND": "django.template.backends.django.DjangoTemplates",
        "DIRS": [
            "/home/html/example.com",
            "/home/html/default",
        ],
    },
    {
        "BACKEND": "django.template.backends.jinja2.Jinja2",
        "DIRS": [
            "/home/html/jinja2",
        ],
    },
]

اگر فراخوانی کنیم:


get_template("story_detail.html")

جنگو به ترتیب زیر جستجو می‌کند:

  • /home/html/example.com/story_detail.html
  • /home/html/default/story_detail.html
  • /home/html/jinja2/story_detail.html

استفاده از render_to_string

برای کاهش تکرار در بارگذاری و رندر قالب‌ها، تابع render_to_string ارائه شده است:


from django.template.loader import render_to_string

rendered = render_to_string("my_template.html", {"foo": "bar"})

جمع‌بندی

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

مقدمه

جنگو از یک سیستم قدرتمند برای مدیریت template engines استفاده می‌کند. این سیستم امکان استفاده از چندین موتور قالب، بارگذاری پویا، رندر قالب‌ها و افزودن قابلیت‌های سفارشی را فراهم می‌کند. موتورهای قالب از طریق django.template.engines قابل دسترسی هستند.


دسترسی به موتورهای قالب

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


from django.template import engines

django_engine = engines["django"]
template = django_engine.from_string("Hello {{ name }}!")

کلید 'django' همان مقدار NAME موتور قالب است.


موتورهای داخلی قالب

DjangoTemplates

برای استفاده از موتور قالب جنگو، مقدار BACKEND باید برابر باشد با:


"django.template.backends.django.DjangoTemplates"

اگر APP_DIRS=True باشد، موتور قالب به دنبال پوشه templates در اپلیکیشن‌های نصب‌شده می‌گردد.


گزینه‌های قابل تنظیم در DjangoTemplates

  • autoescape: فعال یا غیرفعال کردن escape خودکار HTML (پیش‌فرض: True).
  • context_processors: لیستی از توابعی که داده‌های اضافی را به context اضافه می‌کنند.
  • debug: فعال‌سازی حالت اشکال‌زدایی قالب.
  • loaders: کلاس‌های بارگذاری‌کننده قالب.
  • string_if_invalid: مقدار خروجی برای متغیرهای نامعتبر.
  • file_charset: کاراکترست فایل‌های قالب (پیش‌فرض: utf‑8).
  • libraries: ثبت کتابخانه‌های تگ سفارشی.
  • builtins: افزودن کتابخانه‌های تگ به صورت پیش‌فرض.

موتور قالب Jinja2

برای استفاده از Jinja2 باید آن را نصب کنید:


pip install Jinja2

سپس مقدار BACKEND را تنظیم کنید:


"django.template.backends.jinja2.Jinja2"

گزینه‌های مهم Jinja2

مهم‌ترین گزینه environment است که مسیر تابع سازنده محیط Jinja2 را مشخص می‌کند. جنگو به صورت خودکار مقادیر زیر را تنظیم می‌کند:

  • autoescape=True
  • loader بر اساس DIRS و APP_DIRS
  • auto_reload=settings.DEBUG
  • undefined بر اساس حالت DEBUG

استفاده از context_processors در Jinja2

استفاده از context processor در Jinja2 توصیه نمی‌شود، زیرا Jinja2 امکان فراخوانی توابع با آرگومان را دارد. بهتر است توابع مورد نیاز را در env.globals قرار دهید.


مثال پیکربندی محیط Jinja2


from django.templatetags.static import static
from django.urls import reverse
from jinja2 import Environment

def environment(**options):
    env = Environment(**options)
    env.globals.update({
        "static": static,
        "url": reverse,
    })
    return env

نمونه استفاده در قالب Jinja2:


Admin

تفاوت تگ‌ها و فیلترها در Jinja2 و DTL

هر دو سیستم از تگ‌ها و فیلترها پشتیبانی می‌کنند، اما Jinja2 به دلیل امکان ارسال آرگومان به توابع، بسیاری از قابلیت‌ها را ساده‌تر پیاده‌سازی می‌کند. همچنین Jinja2 دارای سیستم تست‌ها است که در DTL وجود ندارد.


جمع‌بندی

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

نوشته و پژوهش‌شده توسط دکتر شاهین صیامی

مقالات مرتبط

فریم‌ورک Tasks در Django: راهنمای کامل اجرای کارهای پس‌زمینه در Django 6.0

Django 6.0 فریم‌ورک Tasks را معرفی کرده است؛ سیستمی داخلی برای تعریف و صف‌بندی کارهای پس‌زمینه خارج از چرخهٔ request–response. این مقاله نحوهٔ کار Tasks، پیکربندی backendها، تعریف و enqueue کردن Taskها، استفاده از context، و ادغام با سیستم‌های Worker خارجی را توضیح می‌دهد.

ادامه

پشتیبانی Asynchronous در Django: راهنمای کامل Async Views، ORM، Middleware، عملکرد و ایمنی

این مقاله پشتیبانی Django از برنامه‌نویسی غیرهم‌زمان (async) را توضیح می‌دهد. موضوعاتی مانند async views، اجرای Django تحت ASGI، رفتار middleware، قابلیت‌های ORM غیرهم‌زمان، sync_to_async، مدیریت قطع اتصال، نکات عملکردی، و مکانیزم‌های ایمنی Django برای جلوگیری از استفادهٔ ناامن async بررسی می‌شوند.

ادامه

System Check Framework در Django: راهنمای کامل نوشتن، ثبت، اجرا و تست چک‌های سیستمی

System Check Framework در Django مجموعه‌ای از بررسی‌های استاتیک برای تشخیص مشکلات رایج در پروژه است. این مقاله نحوهٔ اجرای چک‌ها، نوشتن چک‌های سفارشی، مدیریت پیام‌ها، برچسب‌گذاری چک‌ها، افزودن چک به مدل‌ها و فیلدها، و نوشتن تست‌های واحد و یکپارچه برای چک‌ها را توضیح می‌دهد.

ادامه

سیگنال‌ها در Django: راهنمای کامل استفاده، اتصال، ارسال و مدیریت Signalها

این مقاله سیستم سیگنال‌های Django را توضیح می‌دهد؛ مکانیزمی برای اطلاع‌رسانی رویدادها بین بخش‌های مختلف برنامه بدون ایجاد وابستگی مستقیم. موضوعاتی مانند نحوهٔ اتصال receiverها، استفاده از decorator، مدیریت senderهای خاص، محل مناسب قرارگیری کد سیگنال‌ها، هشدارهای مهم، و بهترین شیوه‌ها بررسی می‌شوند.

ادامه

آشنایی کامل با Django Settings: پیکربندی، مدیریت محیط، و بهترین شیوه‌ها

این مقاله یک راهنمای جامع دربارهٔ سیستم تنظیمات در Django ارائه می‌دهد. موضوعاتی مانند ساختار فایل تنظیمات، نحوهٔ تعیین DJANGO_SETTINGS_MODULE، استفاده از settings در کد، امنیت، پیکربندی دستی با configure()، استفادهٔ مستقل از Django با django.setup() و ایجاد تنظیمات سفارشی بررسی می‌شوند.

ادامه

سریال‌سازی و دسریال‌سازی در Django: راهنمای کامل کار با Serialization Framework

این مقاله سیستم سریال‌سازی Django را توضیح می‌دهد؛ از نحوهٔ تبدیل مدل‌ها به JSON، XML، YAML و JSONL گرفته تا دسریال‌سازی داده‌ها، سریال‌سازی فیلدهای انتخابی، کار با مدل‌های ارث‌بری، مدیریت روابط، و نکات مهم هنگام ذخیرهٔ داده‌های دسریال‌شده.

ادامه