يسلط الضوء على Django: قوالب حفظ الخطوط (الجزء الثاني)

نشرت: 2022-03-10
ملخص سريع ↬ إنشاء كود الواجهة الأمامية في Django مع القوالب والعرض من جانب الخادم يجمع بين التحكم الدقيق في HTML المكتوب بخط اليد مع الشفرة النظيفة والميزات القوية للصفحات التي تم إنشاؤها. نستكشف تقسيم صفحة ويب معقدة إلى قوالب متعددة ، وإنشاء تلك المكونات ، وتطبيق العلامات والمرشحات لإعادة تشكيل صفحة HTML عادية.

تتطلب بعض الأساليب الخالية من الرتوش لبناء مواقع الويب من المطور كتابة كل سطر من HTML يدويًا. من ناحية أخرى ، يقوم منشئو المواقع التجارية بدون كود بإنشاء كل HTML للمستخدم تلقائيًا ، غالبًا على حساب قابلية القراءة في الكود الناتج. القوالب موجودة في منتصف هذا الطيف ، ولكنها أقرب إلى HTML المكتوبة يدويًا من ، على سبيل المثال ، إنشاء بنية الصفحة في تطبيق من صفحة واحدة باستخدام React أو مكتبة مماثلة. توفر هذه النقطة اللطيفة في السلسلة المستمرة العديد من مزايا HTML اليدوي من البداية (كود دلالي / قابل للقراءة ، وتحكم كامل في بنية الصفحة ، وتحميل سريع للصفحات) وتضيف فصل الاهتمامات والإيجاز ، كل ذلك على حساب قضاء بعض الوقت في الكتابة تعديل HTML يدويًا. يوضح هذا المقال استخدام قوالب Django لكتابة صفحات معقدة.

طيف HTML. (معاينة كبيرة)

موضوع اليوم ينطبق خارج إطار عمل Django. يعتبر كل من Flask (إطار ويب آخر) و Pelican (منشئ موقع ثابت) مجرد اثنين من العديد من مشاريع Python الأخرى التي تستخدم نفس الأسلوب في القوالب. Jinja2 هو محرك القوالب الذي تستخدمه جميع الأطر الثلاثة ، على الرغم من أنه يمكنك استخدام محرك مختلف عن طريق تغيير إعدادات المشروع (بالمعنى الدقيق للكلمة ، Jinja2 عبارة عن مجموعة شاملة من قوالب Django). إنها مكتبة قائمة بذاتها يمكنك دمجها في مشاريعك الخاصة حتى بدون إطار عمل ، لذا فإن التقنيات من هذه المقالة مفيدة على نطاق واسع.

الأجزاء السابقة في السلسلة:

  • يسلط الضوء على Django: نماذج المستخدم والمصادقة (الجزء الأول)
  • يسلط الضوء على Django: النماذج والمسؤول وتسخير قاعدة البيانات العلائقية (الجزء 3)
  • أهم أحداث Django: الأصول الثابتة وملفات الوسائط (الجزء الرابع)
المزيد بعد القفز! أكمل القراءة أدناه ↓

التقديم من جانب الخادم

القالب هو مجرد ملف HTML حيث تم تمديد HTML برموز إضافية. تذكر ما تعنيه HTML: H yper T ext M arkup L anguage. Jinja2 ، لغتنا النموذجية ، تضيف ببساطة إلى اللغة مع رموز ترميز إضافية ذات مغزى. يتم تفسير هذه الهياكل الإضافية عندما يعرض الخادم القالب لخدمة صفحة HTML عادية للمستخدم (أي أن الرموز الإضافية من لغة القوالب لا تدخل في الإخراج النهائي).

التقديم من جانب الخادم هو عملية إنشاء صفحة ويب استجابة لطلب. يستخدم Django العرض من جانب الخادم لخدمة صفحات HTML للعميل. في نهاية تنفيذها ، تجمع وظيفة العرض بين طلب HTTP ، وقالب واحد أو أكثر ، واختيارياً البيانات التي يتم الوصول إليها أثناء تنفيذ الوظيفة لإنشاء صفحة HTML واحدة ترسلها كرد على العميل. تنتقل البيانات من قاعدة البيانات ، من خلال طريقة العرض ، إلى القالب لتشق طريقها إلى المستخدم. لا تقلق إذا لم يكن هذا التفسير المجرد منطقيًا تمامًا ، فسننتقل إلى مثال ملموس لبقية هذه المقالة.

اعداد

على سبيل المثال الخاص بنا ، سنأخذ صفحة ويب معقدة إلى حد ما ، قالب مسؤول بدء Bootstrap ، وإعادة كتابة HTML كقالب Jinja2. لاحظ أن المكتبة المرخصة من معهد ماساتشوستس للتكنولوجيا تستخدم نظامًا مختلفًا للقوالب (يعتمد على JavaScript و Pug) لإنشاء الصفحة التي تراها ، لكن نهجها يختلف اختلافًا جوهريًا عن نموذج Jinja2 ، لذا فإن هذا المثال هو أكثر من هندسة عكسية من الترجمة من مشروعهم الممتاز مفتوح المصدر. لمشاهدة صفحة الويب التي سننشئها ، يمكنك إلقاء نظرة على المعاينة المباشرة لـ Start Bootstrap.

لقد أعددت نموذج تطبيق لهذه المقالة. لتشغيل مشروع Django على جهاز الكمبيوتر الخاص بك ، ابدأ بيئة Python 3 الافتراضية الخاصة بك ، ثم قم بتشغيل الأوامر التالية:

 pip install django git clone https://github.com/philipkiely/sm_dh_2_dashboard.git cd sm_dh_2_dashboard python manage.py migrate python manage.py createsuperuser python manage.py loaddata employee_fixture.json python manage.py runserver

ثم افتح متصفح الويب وانتقل إلى https://127.0.0.1:8000 . يجب أن تشاهد نفس صفحة المعاينة ، مطابقة للصورة أدناه.

الصفحة الرئيسية للوحة القيادة. (معاينة كبيرة)

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

الآن ، نحن جاهزون للمشي خلال عملية تحويل ملف HTML المكون من 668 سطر إلى موقع Django مصمم بشكل صحيح.

النمذجة والوراثة

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

ألق نظرة في الصفحات / القوالب . يجب أن ترى خمسة ملفات:

  • base.html ، القالب الأساسي الذي ستمتد إليه كل صفحة ويب. يحتوي على <head> بالعنوان ، وواردات CSS ، وما إلى ذلك.
  • navbar.html ، HTML لشريط التنقل العلوي ، مكون يتم تضمينه عند الضرورة.
  • footer.html ، رمز تذييل الصفحة ، ومكون آخر يتم تضمينه عند الحاجة.
  • sidebar.html ، HTMl للشريط الجانبي ، مكون ثالث يتم تضمينه عند الحاجة.
  • index.html ، الرمز الفريد للصفحة الرئيسية. يوسع هذا القالب القالب الأساسي ويتضمن المكونات الثلاثة.

يجمع Django هذه الملفات الخمسة مثل Voltron لتقديم صفحة الفهرس. الكلمات الرئيسية التي تسمح بذلك هي {% block %} و {% include %} و {% extend %} . في base.html :

 {% block content %} {% endblock %}

يترك هذان السطران مساحة للقوالب الأخرى التي تعمل على توسيع base.html لإدراج HTML الخاص بها. لاحظ أن content هو اسم متغير ، يمكن أن يكون لديك كتل متعددة بأسماء مختلفة في قالب ، مما يمنح المرونة للقوالب الفرعية. نرى كيفية توسيع هذا في index.html :

 {% extends "base.html" %} {% block content %} <!-- HTML Goes Here --> {% endblock %}

يؤدي استخدام الكلمة الأساسية extends مع اسم القالب الأساسي إلى منح صفحة الفهرس هيكلها ، مما يحفظنا من النسخ في العنوان (لاحظ أن اسم الملف هو مسار نسبي في شكل سلسلة ذات علامات اقتباس مزدوجة). تتضمن صفحة الفهرس جميع المكونات الثلاثة الشائعة في معظم الصفحات على الموقع. نجلب هذه المكونات مع علامات include النحو التالي:

 {% extends "base.html" %} {% block content %} {% include "navbar.html" %} {% include "sidebar.html" %} <!--Index-Specific HTML--> {% include "footer.html" %} <!--More Index-Specific HTML--> {% endblock %}

بشكل عام ، يوفر هذا الهيكل ثلاث مزايا رئيسية على كتابة الصفحات بشكل فردي:

  • كود جاف (لا تكرر نفسك)
    من خلال تضمين التعليمات البرمجية الشائعة في ملفات معينة ، يمكننا تغيير الكود في مكان واحد فقط وعكس هذه التغييرات في جميع الصفحات.
  • زيادة سهولة القراءة
    بدلاً من التمرير خلال ملف عملاق واحد ، يمكنك عزل المكون المحدد الذي تهتم به.
  • فصل المخاوف
    يجب أن يكون رمز الشريط الجانبي ، على سبيل المثال ، في مكان واحد ، فلا يمكن أن يكون هناك أي علامات script محتالة تطفو في الجزء السفلي من الكود أو أي اختلاط آخر بين العناصر التي يجب أن تكون منفصلة. يفرض احتساب القطع الفردية هذه ممارسة الترميز الجيدة.

بينما يمكننا حفظ المزيد من سطور التعليمات البرمجية عن طريق وضع المكونات المحددة في قالب base.html ، فإن الاحتفاظ بها منفصلة يوفر ميزتين. الأول هو أننا قادرون على تضمينها بالضبط في المكان الذي تنتمي إليه في كتلة واحدة (هذا ينطبق فقط على footer.html الذي يدخل داخل div الرئيسي لكتلة content ). الميزة الأخرى هي أنه إذا أردنا إنشاء صفحة ، على سبيل المثال صفحة خطأ 404 ، ولم نكن نريد الشريط الجانبي أو التذييل ، فيمكننا استبعادها.

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

اثنان من العلامات الأساسية

هذا بعيد جدًا عن قائمة شاملة بالعلامات المتاحة. وثائق Django على القوالب توفر مثل هذا التعداد. في الوقت الحالي ، نركز على حالات الاستخدام لاثنين من أكثر العناصر شيوعًا في لغة القوالب. في عملي الخاص ، أستخدم فقط علامة for و if بشكل منتظم ، على الرغم من أن العشرات أو أكثر من العلامات الأخرى المقدمة لها حالات استخدام خاصة بها ، والتي أشجعك على مراجعتها في مرجع النموذج.

قبل أن نصل إلى العلامات ، أريد تدوين ملاحظة حول بناء الجملة. تعني العلامة {% foo %} أن "foo" هي دالة أو قدرة أخرى لنظام القوالب نفسه ، بينما تعني العلامة {{ bar }} أن "الشريط" هو متغير تم تمريره إلى القالب المحدد.

للحلقات

في index.html المتبقي ، يمثل الجدول أكبر قسم من الكود بعدة مئات من الأسطر. بدلاً من هذا الجدول الثابت ، يمكننا إنشاء الجدول ديناميكيًا من قاعدة البيانات. python manage.py loaddata employee_fixture.json من خطوة الإعداد. استخدم هذا الأمر ملف JSON ، يسمى Django Fixture ، لتحميل جميع سجلات الموظفين البالغ عددها 57 في قاعدة بيانات التطبيق. نستخدم طريقة العرض في views.py لتمرير هذه البيانات إلى النموذج:

 from django.shortcuts import render from .models import Employee def index(request): return render(request, "index.html", {"employees": Employee.objects.all()})

الحجة الموضعية الثالثة التي يجب render هي قاموس البيانات الذي يتم إتاحته للقالب. نستخدم هذه البيانات وعلامة for لبناء الجدول. حتى في النموذج الأصلي الذي قمت بتعديل صفحة الويب هذه منه ، كان جدول الموظفين مشفرًا بشكل ثابت. يقطع نهجنا الجديد مئات الأسطر من صفوف الجدول ذات الترميز الثابت المتكررة. يحتوي index.html الآن على:

 {% for employee in employees %} <trv <td>{{ employee.name }}</td> <td>{{ employee.position }}</td> <td>{{ employee.office }}</td> <td>{{ employee.age }}</td> vtd>{{ employee.start_date }}</td> <td>${{ employee.salary }}</td> </tr> {% endfor %}

الميزة الأكبر هي أن هذا يبسط إلى حد كبير عملية تحديث الجدول. بدلاً من قيام مطور بتحرير HTML يدويًا لتعكس زيادة في الراتب أو تعيين جديد ، ثم دفع هذا التغيير إلى الإنتاج ، يمكن لأي مسؤول استخدام لوحة الإدارة لإجراء تحديثات في الوقت الفعلي (https://127.0.0.1/admin ، استخدم بيانات الاعتماد التي قمت بإنشائها باستخدام python manage.py createsuperuser to access). هذه فائدة من استخدام Django مع محرك التقديم هذا بدلاً من استخدامه بمفرده في مولد موقع ثابت أو طريقة قوالب أخرى.

إذا كان غير ذلك

تعد علامة if علامة قوية بشكل لا يصدق تسمح لك بتقييم التعبيرات داخل القالب وضبط HTML وفقًا لذلك. سطور مثل {% if 1 == 2 %} صحيحة تمامًا ، إذا كانت عديمة الفائدة إلى حد ما ، حيث يتم تقييمها بنفس النتيجة في كل مرة. مكان تألق علامة if هو عند التفاعل مع البيانات التي تم تمريرها إلى القالب بواسطة طريقة العرض. ضع في اعتبارك المثال التالي من sidebar.html :

 <div class="sb-sidenav-footer"> <div class="small"> Logged in as: </div> {% if user.is_authenticated %} {{ user.username }} {% else %} Start Bootstrap {% endif %} </div>

لاحظ أنه يتم تمرير كائن المستخدم بالكامل إلى القالب افتراضيًا ، دون تحديد أي شيء في العرض لتحقيق ذلك. يتيح لنا ذلك الوصول إلى حالة مصادقة المستخدم (أو عدم وجودها) واسم المستخدم والميزات الأخرى ، بما في ذلك علاقات المفاتيح الخارجية التالية للوصول إلى البيانات المخزنة في ملف تعريف المستخدم أو نموذج آخر متصل ، كل ذلك من ملف HTML.

قد تشعر بالقلق من أن هذا المستوى من الوصول قد يشكل مخاطر أمنية. ومع ذلك ، تذكر أن هذه القوالب مخصصة لإطار عمل عرض من جانب الخادم. بعد إنشاء الصفحة ، استهلكت العلامات نفسها واستُبدلت بـ HTML خالص. وبالتالي ، إذا قدمت عبارة if بيانات إلى صفحة في ظل بعض الشروط ، ولكن لم يتم استخدام البيانات في حالة معينة ، فلن يتم إرسال هذه البيانات إلى العميل على الإطلاق ، حيث يتم تقييم عبارة if من جانب الخادم. هذا يعني أن النموذج الذي تم إنشاؤه بشكل صحيح هو طريقة آمنة للغاية لإضافة بيانات حساسة إلى الصفحات دون مغادرة تلك البيانات للخادم ما لم يكن ذلك ضروريًا. ومع ذلك ، فإن استخدام قالب Django لا يلغي الحاجة إلى توصيل المعلومات الحساسة بطريقة آمنة ومشفرة ، بل يعني ببساطة أن فحوصات الأمان مثل user.is_authenticated يمكن أن تحدث بأمان في HTML حيث تتم معالجتها من جانب الخادم.

تحتوي هذه الميزة على عدد من حالات الاستخدام الأخرى. على سبيل المثال ، في الصفحة الرئيسية العامة للمنتج ، قد ترغب في إخفاء زري "تسجيل الدخول" و "تسجيل الدخول" واستبدالهما بزر "تسجيل الخروج" للمستخدمين الذين قاموا بتسجيل الدخول. الاستخدام الشائع الآخر هو إظهار وإخفاء رسائل النجاح أو الخطأ لعمليات مثل إرسال النموذج. لاحظ أنك عمومًا لن تخفي الصفحة بأكملها إذا لم يقم المستخدم بتسجيل الدخول. أفضل طريقة لتغيير صفحة الويب بأكملها بناءً على حالة مصادقة المستخدم هي التعامل معها في الوظيفة المناسبة في views.py .

الفلتره

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

 <td>${{ employee.salary|intcomma }}</td>

حرف الأنبوب | هو المرشح الذي يطبق الأمر intcomma على متغير راتب employee.salary . لا يأتي الحرف "$" من النموذج ، فبالنسبة لعنصر مثل هذا الذي يظهر في كل مرة ، يكون من الأسهل إلصاقه خارج العلامة.

لاحظ أن intcomma يتطلب منا تضمين {% load humanize %} في أعلى index.html و 'django.contrib.humanize', في INSTALLED_APPS في settings.py . يتم ذلك من أجلك في نموذج الطلب المقدم.

خاتمة

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

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

أضواء جانغو هي سلسلة تقدم مفاهيم مهمة لتطوير الويب في Django. كُتبت كل مقالة كدليل مستقل لأحد جوانب تطوير Django الذي يهدف إلى مساعدة مطوري الواجهة الأمامية والمصممين على الوصول إلى فهم أعمق لـ "النصف الآخر" من قاعدة الكود. تم إنشاء هذه المقالات في الغالب لمساعدتك على فهم النظرية والاتفاقية ، ولكنها تحتوي على بعض نماذج التعليمات البرمجية ، والتي تمت كتابتها في Django 3.0.

الأجزاء السابقة في السلسلة:

  • يسلط الضوء على Django: نماذج المستخدم والمصادقة (الجزء الأول)
  • يسلط الضوء على Django: النماذج والمسؤول وتسخير قاعدة البيانات العلائقية (الجزء 3)
  • أهم أحداث Django: الأصول الثابتة وملفات الوسائط (الجزء الرابع)