مقدمه
در این بخش، به بررسی سایر عملیات اساسی مدیریت دادهها CRUD در برنامههای تحت وب، یعنی نحوهی ایجاد (Create)، ویرایش (Update) و حذف (Delete) دادههای یک مدل میپردازیم.
در قسمت پایانی بخش قبلی، فرآیند خواندن (Read) دادهها را بررسی کردیم. در آن مثال، با کلیک روی نام پروژه به مسیر read-project/
هدایت میشدیم و جزئیات هر پروژه نمایش داده میشد. این فرآیند، تنها یکطرفه بود: دادهها از پایگاه داده خوانده و به کاربر نمایش داده میشدند، اما هیچ امکانی برای ارسال یا تغییر داده وجود نداشت.
برای پیادهسازی سایر عملیات CRUD که در بالا اشاره شد، نیازمند یک مکانیزم برای دریافت ورودی از کاربر و ارسال آن به سرور هستیم. در دنیای وب، این وظیفه بهعهدهی فرمها (Forms) است. در فریمورک جنگو نیز، فرمها نقش کلیدی در انتقال دادهها بین تمپلیتها (صفحات HTML) و پایگاه داده ایفا میکنند.
مفهوم فرم در HTML
در HTML، یک Form شامل مجموعهای از فیلدها یا ویجتها (widgets) است که برای دریافت داده از کاربر و ارسال آن به سرور استفاده میشود. فرمها ابزارهایی انعطافپذیر هستند که امکان جمعآوری انواع دادهها را از طریق المانهایی مانند text box، checkbox، radio button، انتخابگر تاریخ و... فراهم میکنند.
علاوه بر جمعآوری داده، فرمها میتوانند دادهها را در قالب درخواستهای POST ارسال کنند و از طریق مکانیزمهای امنیتی مانند توکن CSRF (Cross-Site Request Forgery protection) که امنیت نسبی بالایی دارند از حملات امنیتی رایج جلوگیری میکنند. این توکن بهصورت خودکار توسط جنگو در فرمها قرار داده میشود و اطمینان حاصل میکند که درخواستها واقعا از طرف کاربر معتبر ارسال شدهاند.
اگرچه تاکنون بهصورت مستقیم فرمی ایجاد نکردهایم، اما در رابط مدیریت جنگو (Admin Interface) هنگام افزودن پروژهها، در واقع در پسزمینه از یک فرم مبتنی بر مدل Project
استفاده میشد.
سیستم فرم در جنگو
جنگو با فراهم کردن یک چارچوب قدرتمند و انعطافپذیر برای مدیریت فرمها، اجازه میدهد فرمهای دلخواه را تعریف کنیم.این سیستم نهتنها کد HTML مربوط به فرم را بهصورت خودکار تولید میکند، بلکه مراحل اعتبارسنجی دادهها (Validation)، پردازش ورودیها و ذخیرهسازی ایمن در پایگاه داده را نیز تسهیل میکند.
اصلیترین بخش این سیستم، کلاس Form است. جنگو دو نوع فرم ارائه میدهد
-
Form
— برای ساخت فرمهای سفارشی که لزوما به یک مدل متصل نیستند. بهعنوان مثال، فرمهای تماس یا جستجو که دادههایشان مستقیما در پایگاه داده ذخیره نمیشوند. -
ModelForm
— برای ساخت فرمهایی که مستقیما مبتنی بر یک مدل جنگو بوده و بهصورت خودکار فیلدهای مدل را به المانهای فرم تبدیل میکند و تمامی ویژگیهای مرتبط — از جمله نوع ورودی (ویجت)، برچسبها، مقادیر پیشفرض، محدودیتها و پیامهای خطا — را مدیریت میکند.
در اغلب مواقع، از ModelForm
بهویژه هنگام پیادهسازی عملیات CRUD، از ModelForm
استفاده میشود، چرا که توسعه را سریعتر، ایمنتر و کمخطاتر میکند.
تعریف یک ModelForm
تعریف ModelForm
بسیار ساده است و حداقل به دو بخش نیاز دارد:
-
مدل مرجعی که فرم بر اساس آن ساخته میشود ←
model
-
لیستی از فیلدهایی از مدل که باید در فرم نمایش داده شوند. ←
fields
بهطور متعارف، فرمها در یک فایل جداگانه با نام forms.py
در دایرکتوری اپلیکیشن تعریف میشوند. این فایل بهصورت پیشفرض در ساختار پروژهی جنگو وجود ندارد و باید بهصورت دستی ایجاد شود.
coreapp/forms.py
from django.forms import ModelForm
from .import models
class ProjectForm(ModelForm):
class Meta:
model = models.Project
fields = ['title', 'area', 'content', 'tags', ]
- کلاس
ProjectForm
ازModelForm
ارثبری میکند. - در بخش
Meta
، مدل مرجع (Project
) و فیلدهای مورد نظر برای نمایش در فرم مشخص شدهاند. - جنگو بهصورت خودکار برای هر فیلد، المان HTML مناسب (ویجت) را بر اساس نوع دادهی تعریفشده در مدل تولید میکند. مثلا یک فیلد
CharField
به یک<input type="text">
تبدیل میشود، در حالی که یکTextField
به یک<textarea>
تبدیل میگردد.
ProjectForm
) تا با قراردادهای نامگذاری پایتون (PascalCase) هماهنگ باشد.
همانطور که ملاحظه میشود، میتوان سطح مدل را برای مدل خود و با اجرای کلاس Meta
، تعیین نمود.
بسیاری از گزینههای دیگر matadata
کنترل میکنند که کدام پایگاه داده باید برای مدل مورد استفاده قرار گیرد تا بتوان دادهها را ذخیره کرد.
فرآیندی که در بالا جریان مییابد بدین صورت است که جنگو model
مورد اشاره در دستور کد را فراخوانی کرده و فرمی با فیلدهای مورد اشاره در قسمت fields
مبتنی بر نوع دادههای (Data Types) تعریف شده در مدل میسازد.
همچنین برای اطلاع دادن به جنگو برای ساختن فرمی با تمامی فیلدهای تعریف شده در مدل میتوان از __all__
در قسمت fields
استفاده کرد.
fields = '__all__'
نکته: باید توجه داشت که فیلدهایی همانند create و id که بهصورت پیشفرض مقداردهی میشوند و یا فیلدهایی که پارامتر editable = False
داشته باشند در فرم ایجاد شده قرار نخواهند داشت.