oruji.github.io
oruji.github.ioPersian Tutorials
ویرایش: 1396/11/13 19:15
A A

سایت و رابط مدیر در جنگو (Django)

برای طبقه ی خاصی از وب سایت ها، یک رابط مدیر (admin interface) بخشی ضروری زیر ساخت وب سایت می باشد. رابط مدیر یک رابط تحت وب می باشد، که مختص مدیران مورد اعتماد سایت می باشد و اضافه کردن، ویرایش و حذف محتویات سایت را مقدور می سازد. رابطی که شما برای پست کردن به بلاگ خود از آن استفاده می کنید، ابزاری که کاربران برای به روز رسانی مطالبی که برای آن ها ساخته اید به کار می برند و محیطی که مدیران سایت برای اداره ی نقطه نظرات کاربران از آن استفاده می کنند مثال هایی برای استفاده از رابط مدیر می باشند.

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

بنابراین روش جنگو برای این مسائل خسته کننده و تکراری چه می باشد؟ جنگو تنها با چند خط نه بیشتر تمام این کارها را برای شما انجام می دهد. با ساختن رابط مدیر جنگو تمام این مشکلات حل خواهد شد.

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

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

پکیج های django.contrib

مدیر خودکار جنگو بخشی از یک سلسله از عملکرد جنگو می باشد که django.contrib نامیده می شود (بخشی از کد جنگو که حاوی افزودنی های مفید برای هسته فریم ورک یا چارچوب می باشد). می توانید django.contrib در جنگو را معادل کتابخانه ی استاندار پایتون فرض کنید. این پکیج ها به وسیله ی جنگو جمع آوری و تدوین شده اند، به طوری که نیازی به دوباره نویسی برخی از اصول در برنامه ها نمی باشد.

سایت مدیر اولین بخش از django.contrib می باشد که در این کتاب پوشش داده شده است که از نظر فنی، django.contrib.admin نامیده می شود. از خصوصیات دیگر قابل استفاده درون django.contrib می توان سیستم حق دسترسی (django.contrib.auth)، سیستم پشتیبانی از session ها (django.contrib.sessions) و حتی یک سیستم برای نقطه نظرات کاربر (django.contrib.comments)را نام برد. شما خصوصیات مختلف django.contrib را به صورت فردی حرفه ای در جنگو فرا خواهید گرفت، زمان زیادی را در پکیج django.contrib برای بحث در مورد این خصوصیات خواهیم گذاشت.

فعال کردن رابط مدیر

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

ابتدا، چند تغییر در فایل تنظیمات انجام دهید:

  1. django.contrib.admin را به تنظیم INSTALLED_APPS اضافه کنید. (ترتیب قرارگیری محتویات INSTALLED_APPS اهمیت ندارد، ولی در این کتاب برای خوانایی بیشتر آن ها را بر اساس حروف الفبا مرتب کرده ایم.)
  2. اطمینان حاصل کنید که INSTALLED_APPS حاوی 'django.contrib.auth'، 'django.contrib.contenttypes' و 'django.contrib.sessions' می باشد. سایت مدیر جنگو به این سه پکیج نیاز دارد. (در صورتیکه همزمان با تمرینات کتاب یعنی پروژه ی mysite پیش می روید، توجه داشته باشید که در آموزش مدل جنگو این سه پکیج را کامنت کردیم. همین حالا آن ها را از حالت کامنت خارج کنید.)
  3. 1. اطمینان حاصل کنید که MIDDLEWARE_CLASSES حاوی 'django.middleware.common.CommonMiddleware'، 'django.contrib.sessions.middleware.SessionMiddleware' و 'django.contrib.auth.middleware.AuthenticationMiddleware' می باشد (دوباره، در صورتیکه همزمان با تمرینات کتاب پیش می روید، توجه داشته باشید که در آموزش مدل جنگو ایتم های فوق کامنت شده اند، پس آن ها را از حالت کامنت خارج کنید.)

در قدم دوم، دستور python manage.py syncdb را اجرا کنید. دستور فوق جداول پایگاه داده اضافه که رابط مدیر از آنها استفاده می کند را نصب می کند. در اولین باری که دستور sycdb را به 'django.contrib.auth' درون INSTALLED_APPS اجرا می کنید، سوالی مبنی درباره ی ساختن یک superuser از شما پرسیده می شود. در صورتیکه آن را انجام ندهید، نیاز است که دستور python manage.py createsuperuser را به طور جداگانه برای ساختن یک حساب کاربری مدیر اجرا کنید، در غیر اینصورت قادر نخواهید بود به سایت مدیر وارد شوید. (نکته ی مهم: دستور python manage.py createsuperuser تنها زمانی در دسترس خواهد بود که 'django.contrib.auth' درون تنظیم INSTALLED_APPS موجود باشد.)

قدم سوم، اضافه کردن سایت مدیر به URLconf (درون فایل urls.py) می باشد. به صورت پیشفرض، urls.py تولید شده توسط django-admin.py startproject حاوی کدهای کامنت شده ای برای مدیر جنگو می باشد و تمام کاری که شما باید انجام دهید خارج کردن آن کدها از حالت کامنت می باشد. چیزی شبیه به کد زیر لازم است:

# Include these import statements... from django.contrib import admin admin.autodiscover() # And include this URLpattern... urlpatterns = patterns('', # ... (r'^admin/', include(admin.site.urls)), # ... )

با اضافه کردن سایت مدیر به URLconf، حالا می توان سایت مدیر جنگو را در عمل مشاهده کرد. تنها کافیست سرور جنگو را اجرا کرده (python manage.py runserver) و نشانی http://127.0.0.1:8000/admin/ را درون مرورگر جستجو کنید.

استفاده از سایت مدیر

سایت مدیر برای استفاده ی کاربران غیر فنی طراحی شده است، و به همین دلیل می بایست بسیار واضح باشد. با این وجود، ویژگی های اولیه آن را به صورت سریع به شما نشان خواهیم کرد.

اولین چیزی که شما مشاهده خواهید کرد صفحه ی ورود مانند شکل 1-6 می باشد.

با نام کاربری و رمز عبوری که در زمان اضافه کردن superuser ساخته اید وارد شوید. در صورتیکه قادر به وارد شدن نیستید، اطمینان حاصل کنید که واقعا یک superuser ساخته اید (سعی کنید دستور python manage.py createsuperuser را اجرا کنید.)

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

هر نوعی از داده در سایت مدیر جنگو دارای یک change list و یک edit form می باشد. change list ها تمام شیء های در دسترس درون پایگاه داده را نشان می دهند، و edit form ها، اجازه ی اضافه کردن تغییر دادن و یا حذف رکورد های مشخص در پایگاه داده را به شما می دهند.

برای بار گذاری صفحه ی change list برای کاربران بر روی لینک "Change" در ردیف "Users" کلیک کنید.

صفحه ی فوق تمام کاربران موجود در پایگاه داده را نمایش می دهد، می توانید این را به صورت پرس وجو پایگاه داده یک نسخه ی زیبا شده از عبارت SELECT * FROM auth_user تصور کنید. در صورتیکه همراه با مثال های کتاب حرکت می کنید، تنها یک کاربر را مشاهده خواهید کرد، ولی هنگامی که کاربران بیشتری وجود داشته باشد، امکانات مفیدی از قبیل فیلتر کردن، چیدن و جستجوی بین آیتم ها را مشاهده خواهید کرد. امکان فیلتر کردن در سمت راست صفحه موجود می باشد، چیدمان از طریق کلیک کردن روی یک header ستون عملی می شود، و جعبه ی جستجو (search box) در قسمت بالا صفحه می باشد اجازه می دهد بر اساس نام کاربری به جستجو بپردازید.

بر روی نام کاربری که ساخته اید کلیک کنید، فرم ویرایش برای کاربر را مشاهده خواهید کرد.

صفحه ی فوق این اجازه را می دهد که خصوصیات کاربر را تغییر دهید، مانند نام و نام خانوادگی و حق دسترسی های گوناگون. (توجه داشته باشید که برای تغییر رمز عبور کاربر به جای ویرایش کد hash، می بایست بر روی "change password form" در زیر فیلد رمز عبور کلیک کرد.) نکته ی دیگر قابل توجه اینکه فیلدهای مختلف به شکل های مختلف پیاده سازی شده اند؛ به عنوان مثال، فیلد زمان و تاریخ دارای کنترل تقویم، فیلدهای Boolean دارای checkbox ها و فیلدهای حروف حاوی فیلد ساده ی مربوط به متن می باشند.

می توان برای حذف کردن یک رکورد بر روی دکمه ی delete در قسمت پایین سمت چپ از فرم ویرایش کلیک کرد. بسته به شیء هایی که قصد حذف کردن آن را دارید، صفحه ی مربوط به تایید برای حذف رکورد نمایان خواهد شد، به عنوان مثال، در صورتیکه یک ناشر را حذف کنید، هر کتاب مربوط به ناشر نیز حذف خواهد شد!

همچنین می توان با کلیک کردن بر روی "Add" درون ستون مناسب از صفحه ی خانگی مدیر یک رکورد را اضافه کرد. بعد از کلیک صفحه ای با فیلدهای خصوصیات خالی نمایان می شود که آماده برای پر شدن است.

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

هنگامی که یک شیء موجود را ویرایش می کنید، متوجه یک لینک History در قسمت راست بالای صفحه خواهید شد. هر تغییری درون رابط مدیر اتفاق بیافتد در اینجا ثبت خواهد شد، و می توان با کیک کردن بر روی لینک History آن تغییر را بررسی کرد.

اضافه کردن مدل ها به سایت مدیر

یک بخش بسیار مهمی هنوز انجام نشده است. اجازه دهید مدل های خود را به سایت مدیر اضافه کنیم، بنابراین می توان شیء های درون جداول پایگاه داده ی مورد نظر را با این رابط عالی حذف، اضافه و تغییر داد. در این فصل نیز مثال books را دنبال خواهیم کرد که در آن سه مدل به نام های Publisher، َAuthor و book تعریف شده است.

درون دایرکتوری books (mysite/books)، یک فایل با نام admin.py ایجاد کرده و کد زیر درون آن وارد کنید:

from django.contrib import admin from mysite.books.models import Publisher, Author, Book admin.site.register(Publisher) admin.site.register(Author) admin.site.register(Book)

کد فوق برای هر یک از مدل ها یک رابط به مدیر جنگو اضافه می کند.

هنگامی که این کار انجام داده شد، به صفحه ی خانگی مدیر درون مرورگر خود رفته (http://127.0.0.1/admin/)، شما باید قسمت "Books" را با لینک های Authors، Books و Publishers مشاهده کنید. (برای موثر واقع شدن تغییرات می بایست سرور را متوقف کرده و دوباره اجرا runserver کنید)

شما هم اکنون برای هر از این سه مدل یک رابط مدیر در حال کار خواهید داشت. بسیار ساده است!

می توانید زمانی را برای اضافه کردن و تغییر رکوردها اختصاص دهید، تا داده هایی را درون پایگاه داده اضافه کنید. در صورتیکه مثال های آموزش مدل جنگو (ساختن شیء های Publisher) را دنبال کرده و آن ها را حذف نکرده باشید، آن رکوردهای ساخته شده در آموزش مدل جنگو را در صفحه ی لیست تغییرات publisher مشاهده خواهید کرد.

یکی از خصوصیات با ارزشی که می توان در اینجا ذکر کرد، کنترل سایت مدیر برای کلیدهای خارجی و رابطه های چند به چند می باشد، هر دوی این حالت ها در مدل Book وجود دارند، برای یادآوری کد زیر مدل Book می باشد:

class Book(models.Model): title = models.CharField(max_length=100) authors = models.ManyToManyField(Author) publisher = models.ForeignKey(Publisher) publication_date = models.DateField() def __unicode__(self): return self.title

درون صفحه ی "Add book" مدیر (http://127.0.0.1:8000/admin/books/book/add/)، Publisher (یک ForeignKey) با یک جعبه ی انتخاب (select box) نمایش داده شده است، و فیلد Authors (یک ManyToManyField) با یک جعبه ی چند انتخابی (multiple-select box) نمایش داده شده است. هر دو فیلد فوق دارای یک علامت سبز رنگ جمع در جلوی خود می باشند که برای اضافه کردن رکوردهای مرتبط به آن ها می باشد. برای مثال، در صورتیکه شما بر روی آن علامت سبز رنگ جلوی فیلد "Publisher" کلیک کنید، یک پنجره ی pop-up برای اضافه کردن یک ناشر باز می باشد. بعد از آنکه یک ناشر در پنجره ی باز شده ساخته شود، صفحه ی "Add book" با جدید ترین ناشر ساخته شده به روزرسانی می شود.

نحوه ی کار سایت مدیر

در پشت صحنه، سایت مدیر چه طور کار می کند؟ نحوه ی کار آن بسیار ساده می باشد.

هنگامی که جنگو URLconf را هنگام اجرای سرور در urls.py بارگذاری می کند، عبارت admin.autodiscover() که در درون این برای فعال کردن سایت مدیر قرار داده شده است اجرا می شود. این تابع درون تنظیم INSTALLED_APPS به دنبال فایلی به نام admin.py که درون هر یک از ایتم ها جستجو می کند. در صورتیکه admin.py درون یکی از app های داده شده وجود داشته باشد، کد درون آن فایل اجرا می شود.

در فایل admin.py درون app مورد نظر یعنی books، فراخوانی هر admin.site.register() به سادگی مدل داده شده را درون سایت مدیر عضو می کند. سایت مدیر تنها یک رابط ویرایش/تغییر برای مدل های عضو شده را نمایش می دهد.

همانطور که مشاهده شد، سایت مدیر به صورت خودکار Users و Groups را نمایش می دهد که درون app خود یعنی django.contrib.auth می باشند که این app شامل فایل admin.py خود و Users و Groups درون آن می باشد. app های دیگر django.contrib، مانند django.contrib.redirects، نیز خودشان را درون سایت مدیر اضافه می کنند.

از این گذشته، سایت مدیر جنگو تنها یک application جنگو با مدل های خود، view ها و URLpattern ها می باشد. با استفاده از URLconf آن را به برنامه ی خود اضافه می کنید، تنها درون view ها خود از آن استفاده می کنید. می توان template ها، view ها و URLpattern های آن را با رفتن به مسیر django.contrib/admin مشاهده و بازرسی کنید ولی تحریک به تغییر چیزی به طور مستقیم در آنجا نشوید چرا که امکانات استفاده ی غیر مستقیم زیادی برای شما وجود دارد.

ایجاد فیلدهای اختیاری

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

برای تعیین کردن فیلد email اختیاری، مدل Book را ویرایش می کنیم (این مدل درون فایل mysite/books/models.py می باشد.) برای این کار به سادگی blank=True را به مانند مثال زیر به فیلد email اضافه می کنیم:

class Author(models.Model): first_name = models.CharField(max_length=30) last_name = models.CharField(max_length=40) email = models.EmailField(blank=True)

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

تا حالا، بجز متد __unicode__()، مدل های ما به صورت جداول پایگاه داده ما بکار می رفتند یعنی مدل ها عبارات پایتونی معادل عبارات CREATE TABE در SQL بودند. با اضافه کردن blank=True، ما شروع به گسترش دادن مدل فراتر از تعریف ساده ی مشابه با جدول پایگاه داده کرده ایم. حال، کلاس مدل در حال تبدیل شدن به یک مجموعه ی غنی از دانش درباره ی آنچه که شیء های Author هستند و می توانند انجام دهند، می باشد. نه تنها فیلد email یک ستون VARCHAR در پایگاه داده می باشد، بلکه همچنین می دانیم که یک فیلد اختیاری در سایت مدیر جنگو نیز می باشد.

این حالت بدین معنی می باشد که فیلد مورد نظر اختیاری می باشد. حالا می توان نویسندگان را بدون نیاز به تهیه ی آدرس الکترونیک اضافه کرد؛ در صورتیکه فرم مورد نظر را با فیلد خالی آدرس الکترونیک Submit کنید دیگر هیچ پیام "This field is required" با رنگ قرمز مشاهده نخواهید کرد.

هنگامی که blank=True اضافه شد، فرم ویرایش "Add author" را دوباره بارگذاری کنید (http://127.0.0.1:8000/admin/books/author/add/)، متوجه خواهید شد که نام فیلد "Email" دیگر به صورت تو پر و پر رنگ نمی باشد.

ایجاد فیلد های از نوع تاریخ و عددی به صورت اختیاری

نکته ی مهم در رابطه با blank=True این است که انجام این حرکت بر روی فیلدهای از نوع عددی و تاریخ نیازمند مقداری توضیح و پیش زمینه می باشد.

SQL برای تعیین مقدار خالی دارای روش خاص خودش می باشد – یک مقدار ویژه به نام NULL. NULL می تواند به معنای ناشناخته، نامعتبر یا ... معنی شود.

در SQL یک مقدار NULL با یک مقدار رشته ی خالی متفاوت می باشد، درست مثال شیء None در پایتون که با یک رشته ی خالی پایتون ("") متفاوت می باشد. این بدان معنی است که ممکن است یک فیلد حرفی (مانند یک ستون VARCHAR) به طور همزمان هم حاوی مقدار NULL و هم حاوی یک رشته ی خالی باشد.

این موضوع می تواند موجب ابهام و گیجی نا خواسته شود. "چرا این رکورد دارای مقدار NULL ولی آن رکورد دیگر دارای یک رشته ی خالی است؟ ایا تفاوتی وجود دارد، یا فقط داده به صورت نا سازگار وارد شده است؟" و: "چطور می توان تمام رکوردهایی که دارای مقدار خالی می باشند را بدست آورد – ایا می توان هر دو رکوردهای NULL و رشته ی خالی را جستجو کرد، یا یک از آن ها را با مقدار رشته ی خالی انتخاب کرد؟"

برای کمک به خلاص شدن از این قبیل ابهامات، جنگو به صورت خودکار عبارت های CREATE TABLE (که در آموزش مدل جنگو توضیح داده شده اند) اضافه و برای هر ستون مقدار NOT NULL را در نظر می گیرد. برای مثال، کد زیر عبارت تولید شده برای مدل Author در آموزش مدل جنگو می باشد:

CREATE TABLE "books_author" ( "id" serial NOT NULL PRIMARY KEY, "first_name" varchar(30) NOT NULL, "last_name" varchar(40) NOT NULL, "email" varchar(75) NOT NULL ) ;

در اغلب موارد، این حالت پیشفرض برای برنامه مطلوب بوده و شما را از درد سر های تناقض و نا هماهنگی های داده حفظ می کند. و برای بقیه ی قسمت های جنگو به خوبی کار می کند، مانند سایت مدیر جنگو، که در زمان خالی گذاشتن یک فیلد یک رشته ی خالی (نه مقدار NULL) وارد می کند.

ولی برای نوع ستون هایی که رشته ی خالی را به عنوان مقدار معتبر قبول نمی کنند – ازقبیل تاریخ ها، زمان ها، و اعداد، یک استثناء وجود دارد. در صورتیکه سعی کنید یک رشته ی خالی برای ستون های ذکر شده وارد کنید، بسته به نوع پایگاه داده ی شما احتمالا خطای پایگاه داده رخ خواهد. در این حالت، NULL تنها راه برای تعیین مقدار خالی می باشد. در مدل های جنگو، می توان مقدار NULL را با اضافه کردن null=True به یک فیلد تعیین کرد.

در صورتیکه بخواهید اجازه دهید مقادیر خالی در فیلد تاریخ (مانند DateField، TimeField، DateTimeField) یا فیلد عددی (مانند IntegerField، DecimalField، FloatField) قرار گیرند نیاز است از null=True و blank=True با هم استفاده کنید.

اجازه دهید مدل Book را برای اینکه بتوان فیلد publication_date را خالی گذاشت تغییر دهیم:

class Book(models.Model): title = models.CharField(max_length=100) authors = models.ManyToManyField(Author) publisher = models.ForeignKey(Publisher) publication_date = models.DateField(blank=True, null=True)

اضافه کردن null=True پیچیده تر از اضافه کردن blank=True می باشد، زیرا null=True از نظر معنایی پایگاه داده را تغییر می دهد – در این حالت عبارت CREATE TABLE تغییر می کند بدین شکل که NOT NULL از فیلد publication_date حذف می شود. برای کامل کردن این تغییر، نیاز است پایگاه داده به روز رسانی شود.

به دلایلی، جنگو تلاشی برای تغییرات خودکار در شمای پایگاه داده نمی کند، بنابراین مسئولیت اجرای یک عبارت ALTER TABLE هر زمان که که تغییری در مدل ایجاد شد، به عهده خودتان می باشد. می توان از manage.py dbshell برای این منظور استفاده کرد. در کد زیر نحوه ی حذف NOT NULL در این مورد خاص را مشاهده می کنید:

ALTER TABLE books_book ALTER COLUMN publication_date DROP NOT NULL;

(توجه داشته باشید که کد فوق برای پایگاه داده ی PostgreSQL می باشد.)

توضیح و بحث عمیق تر در مورد این تغییرات در آموزش مدل پیشرفته بحث شده است.

به سایت مدیر بر می گردیم، اکنون فرم ویرایش "Add book" اجازه می دهد تا مقدار خالی را برای publication date قرار دهیم.

سفارشی کردن نام فیلدها

در فرم های ویرایش سایت مدیر، نام هر فیلد از روی نام مدل فیلد تولید می شود. الگوریتم آن بسیار ساده می باشد: جنگو تنها خط های تیره (_) را با فاصله ها جایگزین کرده و حروف اول را تبدیل به حروف بزرگ می کند، بنابراین، برای مثال، فیلد publication_date مدل Book دارای نام "Publication date" خواهد بود.

اگر چه نام فیلدها درون مدل به طور زیبایی درون سایت مدیر نیز تغییر می کنند، ولی در برخی موارد ممکن است بخواهید آن نام ها را خودتان تعیین کنید. با استفاده از verbose_name می توان این کار را انجام داد.

برای مثال، در زیر نحوه ی تغییر نام فیلد Author.email به "e-mail" نشان داده شده است:

class Author(models.Model): first_name = models.CharField(max_length=30) last_name = models.CharField(max_length=40) email = models.EmailField(blank=True, verbose_name='e-mail')

تغییر فوق را ایجاد کرده و صفحه را دوباره بارگذاری کنید، شما باید فیلد مورد نظر با نام جدید مشاهده کنید.

توجه داشته باشید، در صورتیکه حرف اول نامی که انتخاب می کند حرف بزرگ نباشد جنگو به طور خودکار آن را تبدیل به حروف بزرگ می کند.

در پایان، توجه داشته باشید که می توان verbos_name را به صوت یک آرگومان موضعی نیز ارسال کرد، کد زیر برابر با مثال قبلی می باشد:

class Author(models.Model): first_name = models.CharField(max_length=30) last_name = models.CharField(max_length=40) email = models.EmailField('e-mail', blank=True)

حرکت فوق برای فیلدهای ManyToManyField و ForeignKey کار نخواهد کرد، زیرا در این فیلدها باید اولین آرگومان یک کلاس مدل باشد. در این موارد، می بایست از verbose_name به صورت واضح استفاده کرد.

کلاس های ModelAdmin مرسوم

نغییراتی که تاکنون اعمال شد – blank=True، null=True و verbose_name – تغییراتی در سطح مدل بوده اند، نه تغییرات در سطح مدیر. خیلی پیش می آید که تغییرات مورد نیاز سایت مدیر در یک بخش از مدل انجام پذیرد و استفاده شوند، هیچ چیز تعیین شده ای برای مدیر وجود ندارد.

گذشته از این، سایت مدیر جنگو امکانات و اختیارات قدترمندی برای سفارشی کردن نحوه ی کار سایت مدیر برای مدل خاص ارائه می کند.

سفارشی کردن لیست های تغییر

اجازه دهید از طریق تعیین کردن فیلدها که درون لیست تغییر برای مدل Author قرار دارند وارد مسائل سفارشی سازی مدیر شویم. به طور پیشفرض، لیست تغییر نتیجه ی __unicode__() برای هر شیء را نمایش می دهد. در آموزش مدل جنگو، متد __uncode__() برای شیء های Author جهت نمایش نام و فامیلی با هم تعریف شد.

class Author(models.Model): first_name = models.CharField(max_length=30) last_name = models.CharField(max_length=40) email = models.EmailField(blank=True, verbose_name='e-mail') def __unicode__(self): return u'%s %s' % (self.first_name, self.last_name)

در نتیجه لیست تغییر برای شیء های Author نام و نام خانوادگی را با هم نمایش می دهد، همانطور که در شکل 8-6 مشاهده می کنید.

می توان این رفتار پیشفرض را با اضافه کردن تعدادی از فیلدها برای تغییر نمایش لیست بهبود بخشید. برای مثال، برای دیدن آدرس الکترونیک هر نویسنده در این لیست، و همچنین اضافه کردن امکان چیدمان بر اساس نام و نام خانوادگی می توان یک کلاس ModelAdmin برای مدل Author تعریف کرد. این کلاس کلید سفارشی سازی مدیر، و یکی از اولیه ترین چیزهایی است که اجازه می دهد لیست فیلدها را جهت نمایش در صفحه ی لیست تغییر تعیین کنید. فایل admin.py را جهت این تغییرات ویرایش کنید:

from django.contrib import admin from mysite.books.models import Publisher, Author, Book class AuthorAdmin(admin.ModelAdmin): list_display = ('first_name', 'last_name', 'email') admin.site.register(Publisher) admin.site.register(Author, AuthorAdmin) admin.site.register(Book)

در زیر مثال فوق، توضیح داده شده است:

با تغییرات فوق، لیست تغییر نویسنده را دوباره بارگذاری کنید، شما حالا در این صفحه سه ستون را مشاهده خواهید کرد – نام، نام خانوادگی و آدرس الکترونیک. علاوه بر آن، هر کدام از این ستون ها قابلیت چیدمان بر اساس سرتیتر ستون را با کلیک کردن رو آن خواهند داشت.

در قدم بعدی اجازه دهید یک نوار جستجوی ساده اضافه کنیم. مانند زیر search_fields را به AuthorAdmin اضافه کنید:

class AuthorAdmin(admin.ModelAdmin): list_display = ('first_name', 'last_name', 'email') search_fields = ('first_name', 'last_name')

صفحه را درون مرورگر دوباره بارگذاری کنید، شما باید یک نوار جستجو را در قسمت بالای صفحه مشاهده کنید (شکل 10-6). در کد فوق تنها به صفحه ی تغییر گفته شده است که یک نوار جستجو برای جستجو بر حسب فیلدهای نام و نام خانوادگی ایجاد کند. همانطور که ممکن است کاربر انتظار داشته باشد، جستجو به حروف کوچک و بزرگ حساس نمی باشد و درون هر دو فیلد صورت می گیرد، بنابراین برای رشته ی "bar" هم نویسنده ای که نام وی Barney بوده را خواهد یافت و هم نویسنده ای که نام خانوادگی وی Hobarson می باشد را خواهد یافت.

در قدم بعدی، اجازه دهید تعدادی فیلتر برای صفحه ی لیست تغییر مدل Book اضافه کنیم:

from django.contrib import admin from mysite.books.models import Publisher, Author, Book class AuthorAdmin(admin.ModelAdmin): list_display = ('first_name', 'last_name', 'email') search_fields = ('first_name', 'last_name') class BookAdmin(admin.ModelAdmin): list_display = ('title', 'publisher', 'publication_date') list_filter = ('publication_date',) admin.site.register(Publisher) admin.site.register(Author, AuthorAdmin) admin.site.register(Book, BookAdmin)

در کد فوق با آیتم های زیادی سر و کار داریم، در کد فوق یک کلاس BookAdmin از نوع ModelAdmin به طور جداگانه ساخته شده است. ابتدا، یک list_display تنها برای ایجاد لیست زیباتر تعریف شده است. سپس، از list_filter استفاده شده است، که فیلدهایی برای استفاده را درون تاپل قرار می دهد و در سمت راست صفحه ی تغییر لیست نمایش داده می شود. برای فیلدهای تاریخ، جنگو میانبرهایی را برای فیلتر لیست می کند "Today"، "Past 7 days"، "This month"و "This year".

list_filter فقط محدود به DateField نمی باشد بلکه با داده های نوع دیگر نیز کار می کند. (سعی کنید با فیلدهای BooleanField و foreignKey هم کار کنید) فیلترها تا زمانیکه حداقل دو مقدار برای انتخاب فرم وجود داشته باشد نمایش داده می شوند.

روش دیگربرای ارائه ی فیلترهای تاریخ استفاده از date_hierarcy مانند کد زیر می باشد:

class BookAdmin(admin.ModelAdmin): list_display = ('title', 'publisher', 'publication_date') list_filter = ('publication_date',) date_hierarchy = 'publication_date'

با اضافه کرد date_hierarchy صفحه ی لیست تغییر یک نوار تاریخ در بالای لیست ایجاد می شود، که در شکل 12-6 مشاهده می کنید، که با یک لیست از سال های در دسترس شروع می کند سپس می توان برای ماه حتی نمایان شدن روز بر روی آن کلیک کرد.

توجه داشته باشید که date_hierarchy یک رشته دریافت می کند، نه یک تاپل، زیرا تنها یک فیلد تاریخ می تواند در آن استفاده شود.

در پایان، اجازه دهید ترتیب چیدمان پیشفرض لیست را به طوری تغییر دهیم که کتاب ها در صفحه ی لیست تغییر همیشه بر اساس تاریخ به صورت نزولی قرار بگیرند. به طور پیشفرض، لیست تغییر شیء ها را بر اساس کلاس Meta مربوط به مدل مودر نظر چیده می شوند (که در آموزش مدل جنگو به آن اشاره شده است.) – ولی شما این مقدار مرتب کردن را تعیین نکرده اید، پس ترتیب تعریف نشده است.

class BookAdmin(admin.ModelAdmin): list_display = ('title', 'publisher', 'publication_date') list_filter = ('publication_date',) date_hierarchy = 'publication_date' ordering = ('-publication_date',)

این اختیار چیدمان مدیر دقیقا به صورت چیدمان در کلاس Meta کار می کند، با این تفاوت که آن تنها از اولین فیلد نام در لیست استفاده می کند. تنها یک لیست یا تاپل از نام فیلدها به آن ارسال کنید و یک علامت (-) در ابتدای فیلد برای چیدمان نزولی آن قرار دهید.

صفحه ی لیست تغییر را برای مشاهده ی حرکت فوق دوباره بارگذاری کنید. توجه داشته باشید که تیتر "Publication date" حالا شامل یک فلش کوچک می باشد که به نحوه ی چیدمان اشاره می کند.

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

سفارشی کردن فرم های ویرایش

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

ابتدا اجازه دهید روش چیده شدن فیلدها را سفارشی کنیم. به طور پیشفرض، ترتیب فیلدها در یک فرم ویرایش مطابق با ترتیبی است که آنها در مدل تعریف شده اند. می توان با استفاده از اختیار fields در کلاس فرزند ModelAdmin آن را تغییر داد:

class BookAdmin(admin.ModelAdmin): list_display = ('title', 'publisher', 'publication_date') list_filter = ('publication_date',) date_hierarchy = 'publication_date' ordering = ('-publication_date',) fields = ('title', 'authors', 'publisher', 'publication_date')

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

نکته ی دیگر مفید در اختیار fields این است که اجازه می دهد بعضی فیلد ها را از قرار داشتن در فرم ویرایش کلا محروم کرد. تنها کافیست، فیلدهایی که نمی خواهید در فرم باشند را درون تاپل قرار ندهید. ممکن است از این امکان هنگامی که کاربران مدیر تنها برای ویرایش بعضی از بخش ها مورد اعتماد هستند استفاده کنید. برای مثال، در پایگاده داده ی کتاب ما، فیلد publication_date از حالت قابل ویرایش بودن خارج و مخفی شده است:

class BookAdmin(admin.ModelAdmin): list_display = ('title', 'publisher', 'publication_date') list_filter = ('publication_date',) date_hierarchy = 'publication_date' ordering = ('-publication_date',) fields = ('title', 'authors', 'publisher')

نتیجتا، فرم ویرایش برای کتاب ها هیچ روشی برای تعیین publication date ارائه نمی کند. این حرکت می تواند در صورتیکه یک ویرایشگر ترجیح می دهد نویسندگانش تاریخ را عقب نزنند مفید باشد.

هنگامی که یک کاربر از این فرم برای اضافه کردن یک کتاب جدید استفاده می کند، جنگو به آسانی مقدار publication_date را None در نظر می گیرد – بنابراین اطمینان حاصل کنید که فیلد مورد نظر دارای null=True می باشد.

استفاده ی عمومی دیگر فرم ویرایش سفارشی برای کار با فیلدهای چند به چند می باشد. همانطور که در فرم ویرایش برای کتاب ها مشاهده کردید، سایت مدیر هر ManyToManyField را به صورت یک جعبه ی چند انتخابه نمایش می دهد، که منطقی ترین راه برای ورودی HTML برای استفاده می باشد – ولی استفاده از جعبه های چند انتخابه می تواند کمی سخت باشد. در صورتیکه که می خواهید چند ایتم را انتخاب کنید، باید برای انجام چنین کاری کلید control و یا در Mac کلید command را نگه پایین نگه داشته و آن ها را انتخاب کنید. سایت مدیر برای این مشکل یک توضیحی را در زیر این فیلد قرار داده است، ولی هنوز هم دارای مشکلاتی می باشد مخصوصا زمانی که فیلد شما حاوی صدها انتخاب باشد.

راه حل سایت مدیر filter_horizontal می باشد. آنرا به BookAdmin اضافه کرده و نتیجه را مشاهده کنید:

class BookAdmin(admin.ModelAdmin): list_display = ('title', 'publisher', 'publication_date') list_filter = ('publication_date',) date_hierarchy = 'publication_date' ordering = ('-publication_date',) filter_horizontal = ('authors',)

فرم ویرایش برای کتاب ها را دوباره بارگذاری کنید، بخش "Authors" حالا از یک رابط جاوا اسکریپت کاراتر استفاده می کند که می توان به راحتی درون انتخاب ها جستجو کردن و هر آنچه را که درون "Available authors" انتخاب می کنید را به درون "Chosen authors" و بر عکس ارسال می کند.

اکیدا توصیه می شود که برای فیلدهای ManyToManyField که بیشتر از 10 ایتم دارند از filter_horizontal استفاده کنید. روش فوق بسیار آسانتر از استفاده از جعبه ی چند انتخابه می باشد. توجه داشته باشید که همچنین می توان برای چندین فیلد نیز از filter_horizontal استفاده کرد – تنها کافیست نام هر کدام را درون تاپل قرار دهید.

کلاس های ModelAdmin همچنین از filter_vertical که تنها در فیلدهای ManyToManyField و نه ForeignKey کار می کند نیز پشتیبانی می کنند، به طور پیشفرض، سایت مدیر برای فیلدهای ForeignKey به سادگی از <select> استفاده می کند، ولی همانطور که برای ManyToManyField نیز از <select> استفاده می شود، ممکن است شما مایل نباشید برای نمایش تمام شیء ها به صورت منوی باز شونده در پایین بار اضافی ای را متحمل شوید. برای مثال در صورتیکه پایگاه داده ی کتاب حاوی صدها ناشر شده باشد، فرم "Add book" مدتی برای بارگذاری زمان خواهد برد، زیرا باید تمام ناشران را برای نمایش در <select> بارگذاری کند.

برای حل این مشکل می بایست از raw_id_fields استفاده کرد. نام فیلد ForeignKey را درون این تاپل قرار دهید، فیلدهای مذکور به جای <select> به صورت یک متن ساده نمایش داده می شوند (<input type="text")

class BookAdmin(admin.ModelAdmin): list_display = ('title', 'publisher', 'publication_date') list_filter = ('publication_date',) date_hierarchy = 'publication_date' ordering = ('-publication_date',) filter_horizontal = ('authors',) raw_id_fields = ('publisher',)

درون جعبه ی ورودی چه چیزی وارد می کنید؟ ID مربوط به پایگاه داده ی ناشر. نمی توان به طور عادی ID هر شخص را به خاطر سپرد، به همین دلیل یک شکل ذره بین نیز در شکل فوق مشاهده می کنید که می توان با کلیک بر روی آن توسط یک پنجره ی pop-up ناشران را که می خواهید اضافه کنید.

کاربران، گروه ها و حق دسترسی ها

بدلیل اینکه با یک superuser وارد می شویم، می توان برای ساختن، ویرایش و حذف کردن هر شیء اقدام کرد. به طور طبیعی، محیط های مختلف نیازمند حق دسترسی های متفاوتی می باشد – بدین صورت نباید باشد که هر شخصی بتواند superuser باشد. سایت مدیر جنگو یک سیستم حق دسترسی را بکاربرده است که می توان برای دادن دسترسی به کاربران خاص برای بخش هایی ار رابط که مورد نیاز است استفاده کرد.

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

کاربران مدیر "Normal"، کاربر superuser نیستند بلکه دارای دسترسی مدیر از طریق دسترسی های اختصاص داده شده به آنها می باشند که می تواند شامل محدودیت های دسترسی باشد. هر شیء قابل ویرایش از طریق رابط مدیر (مانند کتاب ها، نویسندگان، ناشران) دارای سه حق دسترسی می باشد: حق دسترسی ساخت، حق دسترسی ویرایش و حق دسترسی حذف. اختصاص دادن حق دسترسی ها به یک کاربر، محدوده اختیارات آن کاربر را برای ایجاد، حذف و یا اعمال تغییرات تعیین می کند.

زمانیکه یک کاربر می سازید، کاربر ساخته شده هیچ حق دسترسی ای ندارد، و برای دادن حق دسترسی های خاص حاضر می باشد. برای مثال، شما می توانید حق دسترسی ای برای تغیییر ناشران به آن بدهید، ولی حق حذف کردن ناشران را به کاربر ندهید. توجه داشته باشید که این حق دسترسی ها برای هر مدل تعریف شده می باشند و نه برای هر شیء، بنابراین شما می توانید اینطور بگویید که "john می تواند روی هر کتاب تغییر ایجاد کند"، ولی نمی توان گفت "john می تواند بر روی هر کتابی که با Apress منتشر شده است تغییرات ایجاد کند." قابلیت دوم، حق دسترسی های هر شیء می باشد که کمی پیچیده تر بوده و خارج از حوصله ی این کتاب می باشد ولی در مستندات جنگو درباره ی آن صحبت شده است.

یادداشت

نکته

دسترسی به ویرایش کاربران و حق دسترسی ها نیز از طریق سیستم حق دسترسی کنترل شده است. در صورتیکه به شخصی حق دسترسی برای ویرایش کاربران را بدهید، آن شخص قادر به ویرایش حق دسترسی های خود می باشد که این ممکن است آن چیزی نباشد که شما می خواهید! دادن حق دسترسی کاربر برای ویرایش کاربران اساسا تغییر کاربر به superuser می باشد.

همچنین می توان کاربران را به گروه ها اختصاص داد. گروه مجموع ای از حق دسترسی هایی می باشد که برای تمام اعضای آن گروه بکار برده می شود. گروه ها برای دادن حق دسترسی های یکسان به زیرمجموعه ای از کاربران مفید می باشد.

چه زمانی و به چه دلیل از رابط مدیر استفاده می شود و چه زمانی استفاده نمی شود

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

سایت مدیر جنگو زمانی بسیار پر ارزش می شود که کاربران غیر فنی به وارد کردن داده نیاز داشته باشند، در روزنامه جایی که جنگو اولین توسعه را در آنجا پیدا کرد یک گزارش ویژه در مورد کیفیت آب شهری که چیزی شبیه به مراحل زیر بود، ارائه شده بود:

ورای وظایف واضح برای وارد کردن داده، سایت مدیر در موارد دیگر که در زیر آمده است نیز مفید می باشد:

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