تخصيص لوحة التحكم المرفقة مع Django


وصلنا إلى ختام هذه السلسلة وفي الدرس الأخير منها سنتحدث عن لوحة التحكم التي يقدّمها إطار العمل Django بشكل جاهز مع كل مشروع تقوم بإنشائه، ويمكن الاستفادة من لوحة التحكم هذه في إدارة النماذج Models المستخدمة في المشروع إضافة إلى إدارة مجموعات المستخدمين وصلاحياتهم في إجراء التعديلات على الموقع اﻹلكتروني.

main.png

الولوج إلى لوحة التحكم

لنستعرض المسارات الموجودة في ملف mysite/urls.py:

urlpatterns = [
    url(r'^admin/', admin.site.urls),
    url(r'^polls/', include(polls_urls)),
]

نلاحظ هنا وجود مسارين رئيسيين في مشروعنا هذا، وكما هو واضح فإنّ الولوج إلى لوحة التحكم يتطلب استخدام مسار يتضمن الكلمة admin/، وللتأكد من ذلك ابدأ بتشغيل الخادوم الخاص بـ Django ثم توجّه في المتصفّح إلى العنوان التالي:

http://127.0.0.1:8000/admin

ستظهر الشاشة التالية:

pic-001.png

ما تراه على متصفحك هو صفحة الولوج log-in إلى لوحة التحكم الخاصة بالمشروع، ومن الواضح أننا نحتاج إلى اسم مستخدم وكلمة مرور لنتمكن من الدخول إلى لوحة التحكم. لإنشاء حساب مستخدم يمكنه الولوج إلى لوحة التحكم توجّه إلى سطر اﻷوامر ونفذ الأمر التالي:

python manage.py createsuperuser

سيُطلب منك إدخال اسم المستخدم، ويمكنك استخدام الاسم الذي ترغب به:

Username: admin

ثم سيُطلب منك إدخال عنوان بريدك اﻹلكتروني:

Email address: admin@example.com

والخطوة اﻷخيرة هي إدخال كلمة المرور مرتين:

Password: **********
Password (again): **********
Superuser created successfully.

واﻵن توجه إلى نفس العنوان السابق في المتصفّح، ثم أدخل الاسم وكلمة المرور التي قمت بإدخالها قبل قليل، وستكون قادرًا اﻵن على الولوج إلى لوحة التحكم والتي ستظهر بالشكل التالي:

pic-002.png

نلاحظ في هذه الصفحة إمكانية تعديل بعض اﻷمور الخاصة بالمستخدمين ومجموعات المستخدمين، ولكن لا نرى ذكرًا لتطبيقنا على اﻹطلاق. سنحتاج في الواقع إلى القيام بخطوة إضافية، وهي إخبار لوحة التحكم بأنّ عناصر الصنف Question في ملف النماذج models.py تمتلك واجهة لوحة تحكم، وللقيام بذلك توجّه إلى ملف polls/admin.py وأضف إليه اﻷسطر التالية:

from .models import Question

admin.site.register(Question)

والآن قم بإعادة تحميل الصفحة الرئيسية للوحة التحكم، وسترى ظهور التطبيق ضمن عناصر الواجهة:

pic-003.png

ﻻحظ أن Django قادر على تمييز أسماء النماذج واستخلاص أسماء ذات مدلولات أوضح بالنسبة للمستخدم، فقد تعرّف Django في مثالنا هذا على النموذج Question باعتباره نموذجًا يحتوي على عدد من العناصر المتمثلة باﻷسئلة، لذا أضاف (s) الجمع إلى الاسم المعروض في لوحة التحكم.

واﻵن انقر على Questions وسترى قائمة باﻷسئلة التي أضفناها برمجيًا إلى النموذج Question في الدروس السابقة.

pic-004.png

يمكنك كذلك النقر على نص السؤال لتتمكن من تعديله أو حذفه:

pic-005.png

ﻻحظ كيف أن Django قد قام بإنشاء استمارة Form خاصة بالسؤال تتضمن جميع الحقول التي أضفناها في الصنف Question في الملف polls/models.py، إضافة إلى ذلك، يستخدم Django عناصر HTML المناسبة لكل نوع من أنواع الحقول. كذلك يضيف Django بعض شيفرات Javascript مع كل حقل من نوع DateTimeField لاختيار الوقت والتاريخ حسب الحاجة.

تخصيص لوحة التحكم

رأينا كيف قام Django ببناء لوحة التحكم والاستمارات الخاصة بالنموذج Question بشكل آلي، ولكن سنحتاج غالبًا إلى تخصيص مظهر لوحة التحكم وآلية عملها، ويمكننا القيام بذلك عند تسجيل النموذج في ملف polls/admin.py؛ لذا توجّه إلى هذا الملف وعدّله بالشكل اﻵتي:

from django.contrib import admin

from .models import Question


class QuestionAdmin(admin.ModelAdmin):
    fields = ['pub_date', 'question_text']

admin.site.register(Question, QuestionAdmin)

عرفنا في الشيفرة السابقة صنف model admin وقمنا بتمريره كمعامل ثانٍ للدالة register(). ستعمل هذه الشيفرة على تبديل مواقع حقلي تاريخ نشر السؤال ونص السؤال، ليحل أحدهما محل اﻵخر:

pic-006.png

يمكن كذلك تقسيم الحقول إلى مجموعات fieldsets وذلك بالشكل التالي:

from django.contrib import admin

from .models import Question


class QuestionAdmin(admin.ModelAdmin):
    fieldsets = [
        (None,               {'fields': ['question_text']}),
        ('Date information', {'fields': ['pub_date']}),
    ]

admin.site.register(Question, QuestionAdmin)

pic-007.png

التعامل مع الاختيارات المرتبطة بالسؤال؟

لم نتعامل لحدّ اﻵن مع الاختيارات المرتبطة باﻷسئلة في تطبيق الاقتراعات، وفي الواقع هنا طريقتان للقيام بذلك:
الطريقة اﻷولى هي اتباع نفس الخطوات التي قمنا باتباعها في تسجيل الصنف Question وذلك بتعديل ملف polls/admin.py ليصبح بالشكل التالي:

from .models import Choice, Question
# ...
admin.site.register(Choice)

قمنا في هذا الشيفرة باستيراد الصنف Choice إضافة إلى الصنف Question، بعد ذلك سجّلنا الصنف Choice باستخدام الدالة register(). واﻵن ستظهر الصفحة الرئيسية للوحة التحكم بالشكل التالي:

pic-008.png

ويمكن إضافة اختيارات جديدة بالضغط على أيقونة Add Choice أو Add وستظهر صفحة إضافة الاختيار بالشكل التالي:

pic-009.png

ﻻحظ أنّه يمكنك اختيار السؤال الذي تودّ ربط الاختيار به وذلك من القائمة المنسدلة المعنونة بـ Question، كما يمكنك إضافة سؤال جديد من هذه الصفحة وذلك بالضغط على علامة (+) الخضراء إلى جانب القائمة المنسدلة، أو تحرير السؤال الذي اخترته بالضغط على أيقونة القلم اﻷصفر.

لا تبدو هذه الطريقة مفيدة من الناحية العملية، إذ يجب إضافة السؤال الجديد، ثم إضافة الاختيارات وربطها واحدًا تلو اﻵخر بالسؤال.

إذًا، أليس من اﻷفضل أن نقوم بإضافة الاختيارات مباشرة عند إضافة السؤال؟ هذه هي الطريقة الثانية.

للقيام بذلك توجّه إلى ملف polls/admin.py ثم عدّله ليصبح بالشكل التالي:

from django.contrib import admin

from .models import Choice, Question


class ChoiceInline(admin.StackedInline):
    model = Choice
    extra = 3


class QuestionAdmin(admin.ModelAdmin):
    fieldsets = [
        (None,               {'fields': ['question_text']}),
        ('Date information', {'fields': ['pub_date'], 'classes': ['collapse']}),
    ]
    inlines = [ChoiceInline]

admin.site.register(Question, QuestionAdmin)

تخبر الشيفرة السابقة Django بأن الاختيارات يتم تحريرها في صفحة التحكم بالسؤال، إضافة إلى تقديم الحقول اللازمة ﻹضافة 3 اختيارات مع كل سؤال. بناء على ذلك ستظهر صفحة إضافة سؤال جديد بالشكل التالي:

pic-010.png

ستبرز هنا مشكلة صغيرة وهي أنّه في حال وجود عدد كبير من الاختيارات، فإن المساحة التي ستشغلها هذه الاختيارات ستكون كبيرة جدًّا. يقدّم Django طريقة أخرى لعرض الاختيارات وهي على شكل جدول، ويمكن الوصول إليها بتعديل المعامل في الصنف ChoiceInline ليصبح بالشكل التالي:

class ChoiceInline(admin.TabularInline):

ستظهر صفحة إضافة سؤال جديد بالشكل التالي:

pic-011.png

واﻵن بعد أن أجرينا التعديلات اللازمة على صفحة إضافة اﻷسئلة، لنجر بعض التعديلات كذلك على الصفحة الرئيسية التي يتم من خلالها عرض جميع اﻷسئلة المتوفرة في التطبيق.

في البداية تظهر هذه الصفحة بالشكل التالي:

pic-012.png

يستخدم Django بصورة افتراضية مخرجات دالة str() لكل حقل من حقول قاعدة البيانات التي يتم عرضها في الصفحة الرئيسية، ولكننا بحاجة هنا إلى عرض جميع الحقول وليس حقل نصّ السؤال فقط. وللقيام بذلك نستخدم الصف list_display والذي سنضمنه أسماء الحقول التي نرغب في عرضها على شكل أعمدة في الصفحة الرئيسية. توجّه إلى ملف polls/admin.py وعدّل الصنف QuestionAdmin لصبح بالشكل التالي:

class QuestionAdmin(admin.ModelAdmin):
    fieldsets =[
        (None, {'fields': ['question_text']}),
        ('Date information', {'fields': ['pub_date'], 'classes':
            ['collapse']}),
    ]
    inlines = [ChoiceInline]
    list_display = ('question_text', 'pub_date', 'was_published_recently')

واﻵن يفترض أن تظهر الصفحة الرئيسية بالشكل التالي:

pic-013.png

ﻻحظ أن Django قام بتسمية العمود اﻷخير بنفس اسم التابع المستخدم في النموذج Question مع استبدال الشرطات السفلية بفواصل، ويمكننا تغيير هذا الاسم وتحسين طريقة عرض المخرجات في هذا العمود بالتوجه إلى ملف polls/models.py وتعديل الصنف Question ليصبح بالشكل التالي:

class Question(models.Model):
    question_text = models.CharField(max_length=200)
    pub_date = models.DateTimeField('date published')

    def __str__(self):
        return self.question_text

    def was_published_recently(self):
        now = timezone.now()
        return now - datetime.timedelta(days=1) <= self.pub_date <= now
    was_published_recently.admin_order_field = 'pub_date'
    was_published_recently.boolean = True
    was_published_recently.short_description = 'Published recently?'

أعد تحميل الصفحة الرئيسية ولاحظ الفرق:

pic-014.png

يمكننا إضافة المزيد من التحسينات إلى هذه الصفحة، فمثلًا يمكننا إضافة عمود جانبي يعمل على تصفية اﻷسئلة حسب تاريخ نشرها، وللقيام بذلك أضف السطر التالي إلى الصنف QuestionAdmin:

list_filter = ['pub_date']

سيضيف هذا السطر عمودًا جانبيًا إلى الصفحة الرئيسية يتيح لمدير الصفحة تصفية اﻷسئلة حسب تاريخ النشر.

ولكن ماذا لو أردنا البحث عن نص سؤال معين بدلًا من البحث بحسب تاريخ النشر؟ يمكن القيام بذلك بإضافة السطر التالي إلى الصنف QuestionAdmin والذي سيعمل على إظهار صندوق للبحث في الصفحة الرئيسية:

search_fields = ['question_text']

بعد إجراء التعديلات السابقة ستظهر الصفحة الرئيسية بالشكل التالي:

pic-015.png

تعديل مظهر لوحة التحكم الخاصّة بالتطبيق

من المؤكّد أننا لا نرغب في ظهور عبارة Django administration في رأس كل صفحة من صفحات لوحة التحكم، ويمكن تغيير هذه العبارة باستخدام نظام قوالب Django، فلوحة التحكم هذه تدار بواسطة Django، وتستخدم الواجهة نظام قوالب Django كذلك.

أنشئ مجلّدًا باسم templates في مجلّد المشروع (المجلد الذي يحتوي على الملف manage.py)، ثم توجّه إلى ملف اﻹعدادات الخاص بالمشروع mysite/settings.py ثم أضف الخيار DIRS إلى إعدادات القالب بالشكل التالي:

TEMPLATES = [
    {
        'BACKEND': 'django.template.backends.django.DjangoTemplates',
        'DIRS': [os.path.join(BASE_DIR, 'templates')],
        'APP_DIRS': True,
        'OPTIONS': {
            'context_processors': [
                'django.template.context_processors.debug',
                'django.template.context_processors.request',
                'django.contrib.auth.context_processors.auth',
                'django.contrib.messages.context_processors.messages',
            ],
        },
    },
]

يحدّد السطر الذي أضفناه إلى إعدادات قوالب المسارات التي يجب على Django البحث فيها عن القوالب، وهنا أخبرنا Django بأن عليه البحث عن المجلد templates ضمن المجلد الرئيسي للمشروع BASE_DIR.

تعمل الدالة os.path.join على ربط القيمة التي يتم الحصول عليها من BASE_DIR مع اسم المجلد المطلوب وهو templates.

واﻵن أنشئ مجلّدًا جديدًا باسم admin داخل مجلد templates الذي أنشأناه قبل قليل، ثم انسخ إليه القالب base_site.html من مجلد admin الموجود ضمن الملفات المصدرية لـ Django في المسار django/contrib/admin/templates.

إن واجهت صعوبة في العثور على الشيفرة المصدرية الخاصة بـ Django توجّه إلى سطر اﻷوامر ونفّذ اﻷمر التالي:

python -c "import django; print(django.__path__)"

واﻵن قم بتحرير ملف base_site.html واستبدل الشيفرة {{ site_header|default:_('Django administration') }} بالعبارة التي ترغب في ظهورها في رأس كل صفحة من صفحات لوحة التحكم، يجب أن تكون الشيفرة مقاربة لما يلي:

{% block branding %}
<h1 id="site-name"><a href="{% url 'admin:index' %}">Polls Administration</a></h1>
{% endblock %}

pic-016.png

من هنا نلاحظ إمكانية إجراء أي تعديل نرغب به على أي قالب من القوالب الخاصة بلوحة التحكم بنفس الطريقة السابقة، فكل ما علينا فعله هو نسخ القالب المطلوب من الملفات المصدرية لـ Django ولصقه في المجلد المخصّص له، ثم إجراء التعديلات المطلوبة.

فعلى سبيل المثال، يمكن تخصيص مظهر الصفحة الرئيسية للوحة التحكم وذلك من خلال نسخ الملف template/index.html من الملفات المصدرية لـ Django بنفس الطريقة السابقة، ثم قم بتحرير الملف، وستجد أنّه يستخدم متغيرًا يحمل الاسم app_list. يتضمن هذا المتغير جميع التطبيقات المثبتة في المشروع الذي تعمل عليه. يمكنك اﻵن استبدال هذا المتغير بروابط تأخذ المستخدم إلى مواضع مختلفة من لوحة التحكم، بدلًا من عرض جميع التطبيقات.

تغيير لغة العرض في لوحة التحكم

من الخصائص التي يتميّز بها إطار العمل Django دعمه للكثير من اللغات، ومن ضمنها اللغة العربية، ويمكن تغيير لغة واجهة لوحة التحكم إلى اللغة التي نرغب بها من خلال التوجّه إلى ملف اﻹعدادات الخاصّ بالمشروع setteings.py ثم تعديل قيمة المتغير LANGUAGE_CODE الافتراضية 'en' إلى رمز اللغة المطلوبة.

فمثلًا لتغيير لغة الواجهة إلى العربية:

LANGUAGE_CODE = 'ar'

pic-017.png

وللغة الفرنسية:

LANGUAGE_CODE = 'fr'

pic-018.png

المصدر:
توثيقات Django



1 شخص أعجب بهذا


تفاعل الأعضاء


لا توجد أيّة تعليقات بعد



يجب أن تكون عضوًا لدينا لتتمكّن من التعليق

انشاء حساب جديد

يستغرق التسجيل بضع ثوان فقط


سجّل حسابًا جديدًا

تسجيل الدخول

تملك حسابا مسجّلا بالفعل؟


سجّل دخولك الآن