لوحة المتصدرين
المحتوى الأكثر حصولًا على سمعة جيدة
المحتوى الأعلى تقييمًا في 03/30/17 في كل الموقع
-
أقرّ أنّي لست خبيرة بتهيئة المواقع لمحركات البحث (Search Engine Optimization (SEO. ربّما كان السبب مجرّد تكاسل من جانبي، أو لأنني كنت مشغولة جدًا بأمور أخرى. السبب الآخر المحتمل الذي منعني من التعمّق أكثر في SEO هو التغيّر الدائم في عالم خوارزميات جوجل، والذي يمكن أن يكون مربكا جدا ومهوّلا بشكل لا يصدق. في الحقيقة، يجب عليك كمدون ألّا تقلق حول SEO، لأن مدونتك بحد ذاتها، تقوم وبشكل طبيعي بالأمور التي يفضّلها جوجل، ولذلك ربما سيكون لديك SEO أفضل من المواقع التقليدية ببساطة عند طريق امتلاك مدوّنة. بالرغم من ذلك، هناك الكثير لتعلّمه، وهناك الكثير مما يمكنك القيام به للمساعدة في رفع ترتيبك Ranking في جوجل وتهيئة مدونتك لمحركات البحث بشكل عام. فإذا كنت مستعدا لتبدأ، تابع معنا هذه السلسلة. في هذا المقال والمقالات القادمة سنلقي نظرة على: العوامل التي تؤثر على ترتيب الموقع/المدونة في جوجل الكلمات المفتاحية: كيفية اختيارها، وما هي أفضل الكلمات؟ وسوم Metatag: هل ما زالت تُستخدم؟ وهل يصلح استخدامها؟ الصور: كيف يمكن أن تؤثر الصور التي أستخدمها على SEO مدونتي؟ الروابط: الروابط الخارجية، الروابط الخلفية backlinks... ماهي؟ نصائح وحيل لتحسين SEO مدونتك. إضافات ووردبريس التي ستساعدك على تحسين وإدارة SEO مدونتك. شراء إعلانات PPC (الدفع مقابل النقرة Pay Per Click). كيف يمكنك كتابة مقالات مدونة بحيث لا تبدو وكأنّها مكتوبة آليا لأنّها مهيأة لمحركات البحث؟ أؤكد لك، سيكون هذا الأمر ممتعا إلى حد كبير، لننطلق! 6 أساسيات SEO للمدونين سواء كنت قد أطلقت مدونتك للتو، أو قد فعلت ذلك منذ فترة مضت، سأشاركك في هذه الفقرة بعض أساسيات SEO للمدونين. وهي عبارة عن بعض العناصر التي يجب أن تتأكد من وجودها على موقعك والتي ستساعدك في تهيئة مدونتك لمحركات البحث وتحسينها. سنلقي نظرة هنا على الأمور التي يجب عليك فعلها للمساعدة في تهيئة مدونتك ككل. وفي مقال لاحق، سنتعلّم كيفية تهيئة كل مقال على حدة. المدونات المستضافة على ووردبريس مقابل المدونات ذاتية الاستضافة إذا كانت مدونتك مُستضافة على ووردبريس فليس هناك الكثير مما يُمكنك القيام به، لذلك من الأفضل أن تكون مدونتك ذاتية الاستضافة self-hosted لتتمكّن من القيام بما ترغب فيه بشكل أفضل. لستُ متأكدة حول مدونات Blogger، والتي نعلم جميعا أنّها تابعة لجوجل، إلا أن SEO مدونة blogpost.com يمكن أن يكون أفضل منه للمدونة المستضافة على ووردبريس. المطلوب منك: سجّل نطاقا domain خاصا لمدونتك (والنطاق المثالي هو اسم مدونتك الذي يحتوي على كلماتك المفتاحية keywords الأساسية)، وقم باستضافة مدونتك على الخادوم الخاص بك. بنية الرابط الثابت Permalink في ووردبريس، يكون الخيار الافتراضي لبنية الرابط الثابت (وهو العنوان المباشر والفريد الذي يتم توليده لكل مقال مفرد تقوم بنشره) مشابها للرابط التالي: http://www.example.com/?p=123 وهذا الرابط فظيع فيما يتعلّق بـ SEO، لأنّ سلسلة الأرقام تلك لا تعني شيئا على الإطلاق. يمكنك أن تحسّن روابطك الثابتة لتكون مهيأة لمحركات البحث، كما سنفصّل في مقال لاحق. لكن للوقت الحالي، اذهب إلى: لوحة التحكم Dashboard > الإعدادات Settings > الروابط الثابتة Permalinks قم باختيار خيار "Post Name" (عنوان المقال) على الأقل، أو أنشئ اسما مخصصا (كما فعلت في الصورة أدناه): وسوم Metatags سابقا، كانت Metatags إحدى الوسائل الأساسية التي تُستخدم لجعل الناس يعثرون على موقعك. وبشكل أساسي، هذه الوسوم هي عبارة عن كلمات مفتاحية تُعرّف ما يتمحور حوله موقعك، وكانت تًضاف بشكل مُباشر إلى شيفرة الصّفحات، لكي تكون واضحة وقابلة للقراءة من قبل عناكب جوجل Google spiders، لكن ليس بالضرورة أن تكون كذلك للقراء العاديين. لم تعد Metatags مهمة كما سبق، والسبب هو أنّ الناس حاولوا التحايل على النظام وحشو هذه الوسوم بالكلمات المفتاحية التي قد تكون مرتبطة، أو غير مرتبطة بمواقعهم الحقيقية. المطلوب منك: قم بتثبيت ملحق SEO من Yoast على مدونتك، بعد ذلك، انقر على خيار "Titles and Meta". وتحت تبويب "Home" قم بإدخال الكلمات المفتاحية الخاصة بموقعك. خريطة الموقع Sitemap تحتاج إلى خريطة الموقع لكي يعرف جوجل موقعك. تسمح الخريطة لجوجل بالتعرّف على جميع صفحات موقعك ومقالاتك، وكذلك تسرّع قدرة جوجل على فهرسة أي تغييرات تحدث على موقعك. المطلوب منك: قم بتثبيت XML’s Sitemap Generator واستخدمه في إنشاء خريطة لموقعك. أو، إذا كنت قد ثبّتّ ملحق SEO من Yoast يمكنك أن تستخدم خياراته المُتاحة. من لوحة التحكم انقر على SEO> XML Sitemaps، ثم قم بتأشير الخيار العلوي. السرعة مهمة سيتحقق جوجل من سرعة تحميل موقعك، فإذا كان التحميل بطيئا، لن تحصل على ترتيبٍ عالٍ. تعتمد سرعة التحميل على بعض محتويات الصفحة كالصور والفيديوهات (عددها وحجمها). المطلوب منك: قم بفحص سرعة تحميل مدونتك من هنا. ولجعل مدونتك تُحمّل بشكل أسرع، قم بتثبيت ملحق خاص بالتخزين المؤقت مثل Quick Cache، واستخدم صورا بأحجام أقل. النشر المتواصل ببساطة، كلما كثفت جهودك في النشر ستحصل على المزيد من التدفّق traffic. أنا أدرك أنّه ليس باستطاعة كل شخص النشر عدة مرات في الأسبوع، أو حتّى العديد من المقالات في اليوم الواحد، وخصوصا إذا كان المدون شخصا واحدا. مع ذلك، قم بإنشاء جدول والتزم به. ليكن هدفك هو النشر مرة واحدة على الأقل في كل أسبوع. المطلوب منك: قم بإنشاء تقويم تحريري لمدونتك وجدول أوقات نشر المقالات، وكذلك حدد المواضيع التي ستتمحور حولها. سنتحدث في المقالات القادمة حول تهيئة المقالات الفردية، وكذلك حول بعض المفاهيم كالروابط الخلفية، التواصل الاجتماعي، والكلمات المفتاحية. ترجمة -وبتصرّف- للمقالين New Series: SEO For Bloggers و SEO4Bloggers #2: SEO Basics for Bloggers لصاحبته: Rebecca Coleman. حقوق الصورة البارزة: Designed by Freepik.1 نقطة
-
تحدثنا في الدرسين السابقين عن كيفية تنصيب وإعداد إطار العمل Django على أنظمة التشغيل المختلفة، وتعرفنا كذلك على مفهومي المشروع والتطبيق، وقمنا بكتابة العرض الأول وتعرفنا بشكل مختصر على المساراتUrls. وفي الجزء الثالث من هذه السلسلة، سنتطرق إلى النماذج Models وكيفية التعامل مع قواعد البيانات من خلال Django، وسنتعرف خلال الدرس على طريقة ربط قواعد البيانات المختلفة مع Django، وكيفية إنشاء النماذج والتعامل معها وسنتطرق كذلك إلى مفهوم تهجير قواعد البيانات Migration، وسننشئ النموذج الخاص بتطبيق الاقتراعات والذي سيحتضن الأسئلة الخاصة بالاقتراع إضافة إلى الإجابات المرتبطة بالسؤال. النماذج Models أشرنا في الدروس السابقة إلى أن إطار العمل Django يتبع مبدأ العمل MVT، ويشير الحرف M هنا إلى النماذج Models، ويمكن تعريف النماذج بشكل مبسط على أنها وصف للبيانات الموجودة في قاعدة البيانات باستخدام لغة Python، وبمعنى آخر تمثّل النماذج في Django بنية قاعدة البيانات، أي ما ستحصل عليه من إجراء الأمر CREATE TABLE ولكن بلغة Python بدلًا من SQL. يستخدم Django النماذج في التواصل مع قواعد البيانات من خلال تنفيذ أوامر SQL خلف الكواليس وتقديم النتائج التي ترد من هذه الأوامر على هيئة بنية من البيانات تمثل الصفوف في جداول قاعدة البيانات. ولهذا الأسلوب في التعامل مع قواعد البيانات بعض الفوائد، فكتابة النماذج بلغة Python يزيد في الانتاجية، إذ لن يكون المبرمج مضطرًا إلى اتباع قواعد لغة أخرى أثناء العمل على التطبيق ويكون العمل مقتصرًا على لغة python، كما يسهل هذا الأسلوب متابعة النماذج وتتبع التغييرات الحاصلة عليها من خلال أنظمة تتبع الإصدارات كـ Git وغيرها، إضافة إلى ذلك تقدم نماذج Python بعض أنواع البيانات غير المتوفرة في SQL كالبريد الإلكتروني وعناوين URL وغيرها. ربط Django مع قواعد البيانات يستطيع Django التعامل مع أنواع مختلفة من أنظمة قواعد البيانات، ومن أشهرها SQLite، MySQL، PostgreSQL و Oracle. وفي مشروعنا هذا سنستخدم قواعد بيانات SQLite والتي تعتبر الخيار الأبسط والأسهل في حالة المشاريع البسيطة والصغيرة ويتم تثبيتها عند تثبيت Python وهذا يعني عدم الحاجة إلى تثبيت أي حزم إضافية، كما أنها ليست بحاجة إلى خادوم خاص تعمل من خلاله. يمكن اختيار نوع قاعدة البيانات التي سيعمل عليها المشروع من خلال ملف الإعدادات settings.py، وذلك ضمن القاموس DATABASES. يستخدم Django قواعد بيانات SQLite بشكل افتراضي، وستجد قاموس DATABASES بالشكل التالي: DATABASES = { 'default': { 'ENGINE': 'django.db.backends.sqlite3', 'NAME': os.path.join(BASE_DIR, 'db.sqlite3'), } } يتطلب ربط Django بقواعد البيانات الأخرى كـ MySQL و PostgreSQL تثبيت حزم الربط الخاصة بكل نوع منها، وإضافة العناصر ‘USER’، ‘PASSWORD’، و’HOST’ إلى القاموس، ويمكن التعرف إلى الحزم المطلوبة لكل نوع من أنواع قواعد البيانات في توثيقات Django. إنشاء النموذج الأول سيعتمد تطبيق الاقتراعات على نموذجين فقط هما نموذج الأسئلة ونموذج الإجابات، وسيتضمن النموذج الأول السؤال وتاريخ نشره، أما النموذج الثاني فسيتضمن الإجابات ومجموع الأصوات على كل إجابة، وسترتبط كل إجابة بسؤال معين. افتح ملف models.py في محرر النصوص المفضل لديك، ثم أضف الأسطر التالية: class Question(models.Model): question_text = models.CharField(max_length=200) pub_date = models.DateTimeField('date published') class Choice(models.Model): question = models.ForeignKey(Question) choice_text = models.CharField(max_length=200) votes = models.IntegerField(default=0) يمكن أن نلاحظ أن كل نموذج في هذا الملف قد تم تمثيله بصنف والذي يمثل بدوره جدولًا في قاعدة البيانات، ويتضمن كل صنف عددًا من المتغيرات التي يمكن استخدامها في شيفرة Python حسب الحاجة إليها، كما تمثل اسم العمود في قاعدة البيانات. تمثل أسماء المتغيرات التي استخدمناها في الشيفرة السابقة أسماء الأعمدة في قواعد البيانات، وسنستخدم هذه الأسماء في شيفرة Python وستظهر كذلك في لوحة التحكم التي سنتحدث عنها مفصّلًا في الدروس القادمة، ويمكن التحكم في طريقة عرض هذه الأسماء في لوحة التحكم وذلك باستخدام معامل يجب تعيين قيمته قبل أي معامل آخر، كما فعلنا مع المتغير pub_date أعلاه، وبهذه الطريقة سيظهر هذا الحقل في لوحة التحكم بالاسم date published وليس pub_date. نلاحظ في الشيفرة السابقة أيضًا أننا عرّفنا علاقة تربط بين الإجابات وبين السؤال الخاص بها، وذلك باستخدام ForeignKey والتي تخبر Django بأن كل إجابة ترتبط بسؤال واحد فقط. تمتلك بعض أنواع الصنف Field عددًا من المعاملات الإلزامية، كما هو الحال مع CharField والذي يتطلب تحديد العدد الأقصى للحروف من خلال max_length. وبطبيعة الحالة تمتلك هذه الأصناف بعض المعاملات الاختيارية، كما هو الحال مع IntegerField الذي أضفنا إليه قيمة افتراضية مساوية للصفر من خلال default=0. يتم تمثيل كل حقل من حقول قاعدة البيانات بـ instance للصنف Field، مثل CharField لحقول الحروف، و DateTimeField لحقول التاريخ والوقت. يقدّم Django عددًا كبيرًا ومتنوعًا من أنواع الحقول، نورد فيما يلي بعضًا منها: الحقل الوظيفة BooleanField يتضمن قيمتي True و False، وعادة ما يكون مرتبطًا بمربع الاختيار Checkbox. CharField يستخدم هذا الحقل لإضافة السلاسل النصية Strings القصيرة والمتوسطة الحجم. DateField يستخدم للتعبير عن التاريخ. DateTimeField يستخدم للتعبير عن التاريخ الوقت. DecimalField يتيح استخدام الأرقام العشرية التي تحتوي على فواصل. EmailField عبارة عن حقل حرفي `CharField` ولكنه قادر على التحقق من أن القيمة المدخلة تمتلك صيغة بريد إلكتروني سليمة. FileField يستخدم هذا الحقل لاحتواء الملفات المرفوعة. IntegerField يتيح استخدام الأرقام الصحيحة، ويمكن استخدام الأرقام من -2147483648 إلى 2147483647 بشكل آمن مع أنظمة قواعد البيانات المختلفة. GenericIPAddressField عبارة عن عنوان IPv4 أو IPv6 على هيئة سلسلة نصية. SlugField حقل Slug. TextField يستخدم في لإضافة السلاسل النصية الطويلة. TimeField يستخدم للتعبير عن الوقت. URLField عبارة عن حقل حرفي يتضمن عنوان URL. تفعيل النموذج تستطيع الشيفرة السابقة القيام بأمور كثيرة، حيث يمكن لـ Django أن: ينشئ جدولًا جديدًا خاصًّا بتطبيقنا هذا وذلك بتنفيذ العبارة CREATE TABLE. إنشاء واجهة برمجية API خاصة يمكن من خلالها التعامل مع قاعدة البيانات التي تم إنشاؤها. ولكن قبل أن يشرع Django بأداء هذه المهام، يجب علينا تثبيت تطبيق polls في مشروعنا وذلك من خلال إدراج اسمه ضمن قائمة INSTALLED_APPS في ملف الإعدادات settings.py، لذا توجه إلى هذا الملف وابحث عن القائمة التي تحمل الاسم INSTALLED_APPS، ثم عدل عناصرها لتصبح بالشكل التالي: INSTALLED_APPS = [ 'django.contrib.admin', 'django.contrib.auth', 'django.contrib.contenttypes', 'django.contrib.sessions', 'django.contrib.messages', 'django.contrib.staticfiles', 'polls', ] توجّه الآن إلى مجلد المشروع عن طريق سطر الأوامر ونفّذ الأمر التالي: python manage.py makemigrations polls يفترض أن ترى النتيجة التالية في سطر الأوامر: Migrations for 'polls': polls/migrations/0001_initial.py: - Create model Choice - Create model Question - Add field question to choice وظيفة الأمر makemigrations هي إخبار Django بأنّك قد أجريت بعض التعديلات على النماذج وأنّك ترغب في حفظ هذه التعديلات على هيئة ملف تهجير يُحفظ على القرص الصلب كملف بايثون في مجلد migrations، تحت اسم: 0001_initial.py. والآن نفّذ الأمر التالي في سطر الأوامر وذلك لتنفيذ التهجيرات وإنشاء الجداول ضمن قاعدة البيانات: python manage.py migrate يفترض أن تظهر النتيجة التالية في سطر الأوامر: Operations to perform: Apply all migrations: admin, auth, contenttypes, polls, sessions Running migrations: Rendering model states... DONE Applying polls.0001_initial... OK تتلخص وظيفة الأمر migrate في البحث عن التهجيرات غير المنفّذة (يتابع Django التهجيرات غير المنفّذة من خلال جدول خاص في قاعدة البيانات يحمل الاسم django_migrations) وإجرائها على قاعدة البيانات، سواء أكانت هذه التهجيرات تتضمن إنشاء جداول جديدة أو تعديل وتحديث جداول موجودة بالفعل. إذًا يمكن تلخيص عملية إجراء التعديلات على النماذج بالخطوات الثلاثة التالية: إجراء التعديلات على النموذج في ملف models.py. تنفيذ الأمر python manage.py makemigrations لإنشاء التهجيرات المرتبطة بالتعديلات التي تم إجراؤها على النموذج. تنفيذ الأمر python manage.py migrate لتطبيق هذه التعديلات على قاعدة البيانات. الواجهة البرمجية الخاصة بالتعامل مع قاعدة البيانات ذكرنا سابقًا بأن لدى Django واجهة برمجية للتعامل مع قاعدة البيانات، وأفضل طريقة للتعرف على هذه الواجهة هي التعامل المباشر معها من خلال سطر الأوامر وعن طريق صدفة Python. للولوج إلى الصدفة نفّذ الأمر التالي في سطر الأوامر: python manage.py shell أولًا يجب استيراد صنفي النموذج Question و Choice، كما سنحتاج إلى حزمة timezone من مكتبة django.utils للتعامل مع الوقت والتاريخ: from polls.models import Question, Choice from django.utils import timezone يمكن الاستعلام عن جميع الأسئلة الموجودة في جدول Question من خلال الشيفرة: Question.objects.all() وباعتبار أن قاعدة البيانات الخاصة بتطبيقنا هذا خالية تمامًا من الأسئلة، فسنحصل على النتيجة: <QuerySet []> لإنشاء السؤال الأول سنقوم بإنشاء كائن من الصنف Question مع تعريف قيم المعاملات المستخدمة في هذا الصنف وإسناد هذا الكائن إلى متغير، وكما يلي: q = Question(question_text="What's new?", pub_date=timezone.now()) يمكن الآن حفظ السؤال الجديد في قاعدة البيانات من خلال الشيفرة التالية: q.save() والآن، يمكن الوصول إلى جميع المعلومات الخاصة بهذا السؤال وبالشكل التالي: #الحصول على نص السؤال q.question_text #الحصول على تاريخ نشر السؤال q.pub_date # تغيير نص السؤال q.question_text = "What’s up?" q.save() بعد أن أضفنا سؤالًا إلى قاعدة البيانات، سنجري استعلامًا عن جميع الأسئلة في النموذج Question: Question.objects.all() #ستحصل على النتيجة التالية <QuerySet [<Question: Question object>]> نلاحظ أن النتيجة التي حصلنا عليها غريبة بعض الشيء، فالسؤال الذي أضفناه قبل قليل لم يظهر ضمن قائمة الأسئلة، ولحل هذه المشكلة سنحتاج إلى إضافة تابع __str()__ إلى كلا الصنفين، وبالشكل التالي: from django.db import models from django.utils.encoding import python_2_unicode_compatible @python_2_unicode_compatible # إن كنت بحاجة إلى استخدام الإصدار الثاني من بايثون class Question(models.Model): # ... def __str__(self): return self.question_text @python_2_unicode_compatible # إن كنت بحاجة إلى استخدام الإصدار الثاني من بايثون class Choice(models.Model): # ... def __str__(self): return self.choice_text من الضروري استخدام التابع __str__() عند التعامل مع النماذج، لأن نتيجة هذا التابع ستظهر في لوحة التحكم التي يتم إنشائها آليًا من خلال هذه النماذج. وكما قمنا باستخدام أحد التوابع المعرفة مسبقًا في Django فبمقدورنا أن نستخدم توابع مخصّصة تؤدي وظائف ومهام مختلفة، ولتوضيح ذلك، قم باستيراد مكتبة datetime الخاصة بـ Python، ثم أضف الشيفرة التالية في نهاية الصنف Question: import datetime # ... class Question(models.Model): # ... def was_published_recently(self): return self.pub_date >= timezone.now() - datetime.timedelta(days=1) سيقوم هذا التابع بالتحقق من أن السؤال قد تم نشره مؤخّرًا (منذ يوم) أو منذ فترة بعيدة (أكثر من يوم). والآن يمكن استدعاء تابعنا المخصص الجديد بنفس الطريقة التي استدعينا من خلالها تابع الحفظ: q.was_published_recently() افتح الآن صدفة بايثون جديدة، واستورد الأصناف Question و Choice بنفس الطريقة السابقة، ثم نفذ شيفرة الاستعلام عن جميع الأسئلة، ولاحظ الفرق. طرق الاستعلام عن البيانات في Django لا شك أن التطبيقات على أرض الواقع تتضمن قواعد بيانات تحتوي على عدد هائل من البيانات والمعلومات، وهذا يتطلب وسيلة للاستعلام عنها حسب شرط معين، ويقدم Django طرقًا متعددة لإجراء استعلامات مخصصة وبأساليب مختلفة. يقدّم Django ثلاثة توابع خاصة بالصنف QuerySet هي: filter(), exclude(), get()، وجملة الاستعلام عبارة عن معاملات مفتاحية Keyword arguments لهذه التوابع، وتأخذ الصيغة التالية: الحقل__نوع الاستعلام = القيمة. يقوم كل تابع من هذه التوابع الثلاثة بإنشاء كائن جديد للصنف QuerySet يتضمن النتائج التي تم الحصول عليها بعد إجراء الاستعلام. يقوم التابع filter() بإرجاع جميع العناصر المتوافقة مع الاستعلام، أما التابع exclude() فيرجع جميع العناصر غير المتوافقة مع الاستعلام، أما التابع get() فيرجع العنصر الذي يطابق جملة الاستعلام، وفي حالة العثور على أكثر من عنصر واحد يقوم هذا التابع بإطلاق الاستثناء MultipleObjectsReturned وإن لم يعثر على أي عنصر فسيطلق الاستثناء DoesNotExist. إليك بعض الأمثلة التي توضح طريقة عمل هذه التوابع: يمكن البحث عن السؤال الذي يبدأ بعبارة معينة بالشكل التالي: Question.objects.filter(question_text__startswith='What') ستترجم هذه الشيفرة إلى عبارة SQL التالية: SELECT … WHERE question_text LIKE ‘What%’; ويمكن البحث عن سؤال معين من خلال المعرّف الخاص به، فللبحث عن السؤال ذي المعرف رقم 1، يمكن كتابة الشيفرة: Question.objects.filter(id=1) والتي تعادل عبارة SQL التالية: SELECT … WHERE id = 1; مثال على التابع exclude(): Question.objects.exclude(pub_date__gt=datetime.date(2016, 1, 3), question_text = "What’s up?") تترجم هذه الشيفرة إلى عبارة SQL التالية: SELECT … WHERE NOT (pub_date > ‘2016-1-3’ AND question_text = “What’s up?”) يوضح الجدول التالي بعض أنواع الاستعلامات التي يقدّمها Django: نوع الاستعلام الوظيفة exact تطابق تام. iexact تطابق تام مع تجاهل حالة الأحرف. contains البحث عن كلمة مع أخذ حالة الأحرف بنظر الاعتبار. icontains البحث عن كلمة مع تجاهل حالة الأحرف. in البحث ضمن قائمة معينة. gt أكبر من gte أكبر من أو يساوي lt أصغر من lte أصغر من أو يساوي startswith يبدأ بـ istartswith يبدأ بـ مع أخذ حالة الأحرف بنظر الاعتبار. endswith ينتهي بـ iendswith ينتهي بـ مع أخذ حالة الأحرف بنظر الاعتبار. range البحث ضمن مدى معين date البحث عن تاريخ معين year البحث عن سنة معينة month البحث عن شهر معين day البحث عن يوم معين week_day البحث عن أسماء أيام الأسبوع hour البحث عن ساعة minute البحث عن دقيقة second البحث عن ثانية لنستعلم الآن عن السؤال الذي يحمل المفتاح الرئيسي primary key رقم 1 في قاعدة البيانات الخاصة بنا، وإسناد النتيجة إلى متغير: q = Question.objects.get(pk=1) يمكننا الآن الوصول إلى مجموعة الأجوبة choice_set والتي ينشئها Django تلقائيًا عند ربط الأسئلة بالأجوبة من خلال ForeignKey. q.choice_set.all() بطبيعة الحال، فإن مجموعة الأجوبة الخاصة بسؤالنا هذا فارغة، لذا سنقوم بإنشاء بعض الأجوبة وإضافتها إلى هذه المجموعة: q.choice_set.create(choice_text = 'Not much', votes = 0) q.choice_set.create(choice_text = 'The sky', votes = 0) c = q.choice_set.create(choice_text = 'Just hacking again', votes = 0) والآن يمكن التعرف على السؤال المرتبط بالجواب: c.question ويمكن معرفة عدد الأجوبة المتاحة لسؤال معين عن طريق التابع count(): q.choice_set.count() ويمكن حذف إجابة معينة عن طريق التابع delete(): c.delete() خاتمة تعرفنا في هذا الدرس على العنصر الأول من عناصر إطار العمل Django ألا وهو النماذج Models، وتعرفنا كذلك على طريقة التعامل مع قواعد البيانات من خلال هذه النماذج وكيفية تهجيرها والاستعلام عن البيانات برمجيًا. أما الدرس القادم فسيكون عن المسارات URLS وآلية عملها، وكيفية استخدام التعابير النظامية Regular Expressions في إنشائها. المصدر: توثيقات Django.1 نقطة
-
Django هو إطار عمل مجّاني ومفتوح المصدر، مكتوب بلغة Python، وتتبع المشاريع فيه بنية Model-View-Template (عادة ما تختصر إلى MVT). يؤكّد Django على قابلية إعادة الاستخدام Reusability للمكونات وكذلك على التطوير السريع، بالإضافة إلى مبدأ عدم التكرار. تستخدم لغة Python في جميع مفاصل إطار العمل هذا، كالإعدادات ونماذج قواعد البيانات وغيرها. ومن أشهر المواقع التي تستخدم Django هي: Pinterest ،Instagram ،Mozilla ،The Washington Times ،Disqus ،National Geographic وغيرها الكثير. طوّر Django سنة 2003 على يدي المبرمجين Adrian Holovaty و Simon Willson اللذين يعملان في صحيفة Lawrence Journal World، وذلك عندما انتقلا إلى لغة Python لبناء التطبيقات. ثم أطلق Django سنة 2005 تحت رخصة BSD، وقد سمّي بهذا الاسم تيمنًا بعازف الغيتار Django Reinhardt. بنية MVT تنقسم بنية المشاريع في Django إلى ثلاثة أقسام مرتبطة ببعضها البعض، ولكنّها مختلفة عن أطر العمل الأخرى التي تتبع بنية (MVC - Model, View, Controller) مثل Laravel في PHP وغيرها، حيث تتكون المشاريع في Django من النموذج Model والعرض View والقالب Template. يتولى قسم النموذج معالجة البيانات والتعامل معها واسترجاعها، ويدعم Django العديد من قواعد البيانات، مثل: SQlite ،MySQL، و PostgreSQL. أما العرض فعبارة عن مجموعة من دوال Python التي تستجيب لعنوان URL معين، ووظيفة العرض هي تحديد البيانات والمعلومات التي يجب عرضها. أما القالب فهو عبارة عن ملف بصيغة HTML يتم من خلاله تحديد الطريقة التي ستظهر بها المعلومات التي يعرضها قسم العرض. أين المتحكم Controller إذًا؟ المتحكم هنا هو إطار العمل نفسه، أي الآلية التي يتم من خلالها إرسال الطلب إلى العرض المناسب بالاعتماد على عنوان URL محدّد. تثبيت Django إطار العمل Django هو إحدى الحزم الخاصة بلغة البرمجة بايثون، وتوفّر هذه اللغة مدير حزم خاصّ يدعى pip يتم من خلاله تثبيت وتحديث وإزالة الحزم بسهولة ويسر؛ لذا ستكون الخطوة الأولى في تثبيت Django هي التأكد من وجود مدير الحزم pip وتثبيته إن لم يكن متوفّرًا. تنصيب pip لتنصيب إطار العمل Django ستحتاج إلى مدير الحزم الخاصّ بـ Python وهو pip، ولحسن الحظّ فإن pip متوفّر في نسخة Python 2.7.9 وما بعدها، وفي نسخة Python 3.4 وما بعدها. في حال عدم توفّر pip في نسخة Python المنصّبة لديك يمكنك تنصيبه باتباع الخطوات التالية: حمّل الملفّ get-pip.py. توجه في سطر الأوامر إلى المكان الذي حملت فيه الملف السابق، ثم اكتب التعليمة التالية: python get-pip.py استخدام سطر الأوامر لنجرب الآن استخدام مدير الحزم في بايثون لتنصيب Django، توجّه الآن إلى سطر الأوامر ثم اكتب الأمر: pip install django==1.9 هل ظهرت لك رسالة خطأ؟ ما المشكلة، ألم نقم بتنصيب pip قبل قليل؟ هذا صحيح، ولكننا لم نخبر سطر الأوامر بأن يوجّه أي تعليمة تبدأ بكلمة pip إلى مدير حزم بايثون، وللقيام بذلك اتبع الخطوات التالية: في أوبنتو: يجب تنصيب حزمة python3-pip إن كنت تستخدم الإصدار الثالث من بايثون أو python-pip للإصدار الثاني من بايثون، لتتمكن من استخدام pip في سطر الأوامر في أبونتو، وللقيام بذلك اكتب الأمر التالي في سطر الأوامر: sudo apt-get install python3-pip أدخل كلمة المرور الخاصة بك، وستبدأ عملية التثبيت، وبعد الانتهاء يمكنك تنصيب أي حزمة خاصة بلغة بايثون عن طريق سطر الأوامر مباشرة. في نظام Windows: أما في نظام Windows فيجب إضافة السطر التالي: C:\Python34\scripts; إلى مسار النظام System path، وللقيام بذلك اتبع الخطوات التالية: انقر بزر الفأرة الأيمن على أيقونة Computer واختر Properties من القائمة المنسدلة: انقر على أيقونة Advance system settings، وفي مربع الحوار المنبثق اضغط على أيقونة Environment Variables. انقر نقراً مزدوجًا على متغير النظام Path في الجزء السفلي من مربع الحوار المنبثق. أضف السطر السابق إلى نهاية السلسلة النصّية، بعد الفاصلة المنقوطة (;) (إن لم تكن هناك فاصلة منقوطة في نهاية السطر فقم بإضافتها). اضغط Ok ثم أغلق بقية النوافذ بالضغط على Ok. يمكنك الآن استخدام pip من سطر الأوامر مباشرة. البيئة الافتراضية Virtual Environment قبل البدء بتنصيب Django سنعمل على تنصيب أداة مفيدة جدًّا من شأنها المساعدة على ترتيب البيئة البرمجية على حاسوبك. يمكن تجاوز هذه الخطوة، ولكن ينصح بها بشدّة. تعمل البيئة الافتراضية على عزل مشاريع Python أو Django الخاصّة بك عن بعضها البعض، وهذا يعني أن إجراء التعديلات على موقع إلكتروني معيّن لن تؤثّر على المشاريع الأخرى التي تعمل عليها. ستحتوي البيئة الافتراضية على الملفات التنفيذية الخاصة بـ Python بالإضافة إلى نسخة من مكتبة pip يمكنك استخدامها في تنصيب حزم Python المختلفة. سننشئ مجلدًا سيحتوي على البيئة الافتراضية التي سوف ننشئها بعد قليل. mkdir mysite cd mysite يتطلب إنشاء البيئة الافتراضية تنصيب حزمة virtualenv وسنستعين بـ pip للقيام بذلك: pip install virtualenv لاستخدام virtualenv من سطر الأوامر مباشرة في أوبنتو يجب تنصيب الحزمة virtualenv، وللقيام بذلك اكتب الأمر التالي في سطر الأوامر: sudo apt-get install virtualenv بعد اكتمال عملية التنصيب يمكنك إنشاء البيئة الافتراضية بالشكل التالي: virtualenv myvenv ستنشئ هذه الشيفرة بيئة افتراضية وهي عبارة عن مجموعة من المجلدات. لتفعيل البيئة الافتراضية الجديدة في نظام Windows استخدم الشيفرة التالية: myvenv\Scripts\activate أما في نظامي Linux و OS X فاستخدم: source myvenv/bin/activate ملاحظة: قد لا تحصل على النتيجة المرجوّة من الشيفرة السابقة، لذا يمكنك استخدام هذه الشيفرة: . myvenv/bin/activate سيتغيّر سطر الأوامر وذلك بإضافة كلمة (myvenv) إلى بداية السطر، وهذا يعني أن الأمور تسير على ما يرام. ولإغلاق البيئة الافتراضية يمكنك استخدام التعليمة التالية: deactivate تنصيب Django بعد اكتمال الخطوتين السابقتين يمكننا الآن تنصيب Django وذلك بتنفيذ الأمر التالي (انتبه إلى وجود علامتي مساواة لا علامة واحدة): pip install django==1.9 بعد اكتمال عملية التنصيب، وللتأكد من أن الأمور تجري على ما يرام، اكتب الأمر التالي في سطر الأوامر: python3 -c "import django; print(django.get_version())" إن حصلت على رقم النسخة (1.9 في حالتنا هذه) التي قمت بتنصيبها، فقد أصبحت جاهزًا لإنشاء مشروعك الأول على Django. إنشاء المشروع الأول مشروعنا الأول سيكون عبارة عن تطبيق استطلاع بسيط، يتألف من جزئين: موقع عام يتيح مشاهدة الاستطلاعات والتصويت عليها. لوحة تحكم تتيح لنا إضافة وحذف وتعديل الاستطلاعات. هذا المشروع سيكون مبنيًا على الإصدار 1.9 من Django والإصدار 3.4 من Python. في حال كنت تستخدم الإصدار 2.7 من Python فيتوجب عليك حينها إضافة بعض التعديلات على الشيفرة التي تكتبها، وسنشير إلى ذلك في محلّه. انتقل إلى سطر الأوامر وتوجه من خلاله إلى المجلد الذي ترغب استخدامه لإنشاء المشروع، وبإمكانك استخدام أي مجلد تحت أي تسمية وفي أي موقع في القرص الصلب، فلا مشكلة لدى Django في ذلك. لإنشاء المشروع نفّذ الأمر التّالي في سطر الأوامر (انتبه إلى النقطة في نهاية السطر): django-admin startproject mysite . سيعمل هذا الأمر على إنشاء مجلد باسم mysite داخل مجلد المشروع. انتبه كذلك إلى كتابة النقطة في نهاية السطر، فهي توجّه الشيفرة إلى تنصيب Django في المجلد الحالي. البنية الأولية للمشروع يحتوي مجلد mysite الذي أنشأته التعليمة السابقة، على مجموعة الملفات التالية: manage.py /mysite __init__.py settings.py urls.py wsgi.py manage.py، يُوصف هذا الملف بالسكين السويسري، وهو الأداة التي سنستعين بها للقيام بالكثير من الأشياء في إدارة الموقع، وفي تهجير قواعد البيانات وتشغيل الخادوم الخاص بـ Django، وغير ذلك الكثير. المجلد mysite هو حزمة بايثون الخاصة بمشروعنا، وسنستخدم هذا الاسم عندما نرغب في استيراد أي شيء داخله. (مثال mysite.urls). mysite/__init__.py ملف فارغ، ووجوده يعني أن هذا المجلّد هو حزمة من حزم بايثون. mysite/settings.py ملف الإعدادات الخاصة بمشروعنا. mysite/urls.py يحتوي على عناوين URL الخاصة بموقعنا، وهو أشبه ما يكون بجدول المحتويات الخاص بالموقع. mysite/wsgi.py نقطة الولوج إلى الخواديم المتوافقة مع WSGI. تشغيل الخادوم توجه في سطر الأوامر إلى المجلد الذي يحوي الملف manage.py ثم اكتب الأمر التالي: python manage.py runserver وستظهر العبارات التالية في سطر الأوامر: Performing system checks... System check identified no issues (0 silenced). You have unapplied migrations; your app may not work properly until they are applied. Run 'python manage.py migrate' to apply them. February 01, 2016 - 15:50:53 Django version 1.9, using settings 'mysite.settings' Starting development server at http://127.0.0.1:8000/ Quit the server with CONTROL-C. ملاحظة: لا تستخدم هذا الخادوم في المشاريع الإنتاجية على الإطلاق، فالهدف من هذا الخادوم هو استخدامه لأغراض التطوير فقط. أدخل العنوان التالي في متصفح الإنترنت: http://127.0.0.1:8000 ستظهر الصفحة التالية لتشير إلى نجاحنا في إنشاء أول مشروع في Django.1 نقطة
-
يضيف الإصدار 5.3 من Laravel نظاما للإشعارات Notifications يمكن من خلاله إخطار المستخدم بحدوث شيء ما. تُستخدَم الإشعارات، التي تكون عادة على هيئة بلاغات قصيرة، لإعلام مستخدم التطبيق بوقوع أمر ما؛ على سبيل المثال “صدور فاتورة”، “تسجيل مستخدم”، “إعادة تعيين كلمة السّر” أو “نشر درس”؛ حسب طبيعة التطبيق الذي تعمل عليه. يتيح نظام الإشعارات في Laravel 5.3 وسائط عدّة (تُسمّى قنوات Channels) لتوصيل الإشعار: البريد الإلكتروني، الرسائل النصية القصيرة SMS (بالاعتماد على خدمة Nexmo) وخدمة Slack. يمكن أيضا تخزين الإشعارات في قاعدة البيانات من أجل عرضها في واجهة الوِب. سنرى في هذا الدرس كيفية عمل الإشعارات، بأخذ مثال لإشعار يُرسَل إلى بريد المستخدم عند إضافة منشور جديد. تهيئة المشروع نبدأ أولا بتهيئة المشروع الذي سنعمل عليه. أنشئ مشروع Laravel 5.3 جديدا، إن لم يكن لديك واحد جاهز واضبط إعدادات قاعدة البيانات. نستخدم نفس الإعدادات المذكورة في فقرة تهيئة بيئة التطوير من درس أساسيات التخبئة في Laravel؛ مع التعديل عليها قليلا. سنضيف صنفا لبذر المستخدمين: php artisan make:seeder UsersTableSeeder ونعدّل صنف البذر على النحو التالي لإضافة مستخدمَيْن إلى قاعدة البيانات: public function run() { $user1 = [ 'name' => 'Med Ahmed Eyil', 'email' => 'medeyil@laravel.com', 'password' => Hash::make('1234'), ]; $user2 = [ 'name' => 'Fatima Benziane', 'email' => 'fbenziane@laravel.com', 'password' => Hash::make('4567'), ]; User::create($user1); User::create($user2); } ثم ننفّذ البذر: php artisan db:seed يصبح لدينا الآن نموذجان، واحد للمستخدمين وآخر للمنشورات. ننتقل إلى ملف المسارات routes/web.php ونضيف المسار التالي: Route::get('/notify/{user_id}/{post_id}', 'PostsController@notify'); يعني هذا أنه عند زيارة الرابط notify/user_id/post_id/ (حيث user_id وpost_id معرّفا المستخدم والمنشور على التوالي) سيطلُب Laravel تنفيذ الدالة notify في المتحكم PostsController. نعدّل المتحكّم PostsController لإضافة هذه الدالة: public function notify($user_id,$post_id) { $user = User::find($user_id); $post = Post::find($post_id); // todo } سنعود لاحقا لإكمال الدالة notify التي تكتفي لحد الساعة بالعثور على المستخدم والمنشور الممررَيْن إليها في المعطيات. الإشعارات هدفنا هو التالي: يطلُب المتصفح الرابط notify/1/2/ (مثلا) فيُرسَل إشعار عبر البريد إلى المستخدم ذي المعرف 1 يخبره أن المنشور ذا المعرف 2 قد أُضيف إلى الموقع. سنحتاج لبلوغ هذا الهدف لإشعار “إضافة منشور”. ننفذ الأمر التالي لإنشاء هذا الإشعار: php artisan make:notification NewPost ستلاحظ بعد تنفيذ الأمر أعلاه ظهور مجلد جديد باسم Notifications (إن لم يكن موجودا سلفا) متفرع عن المجلد app وبداخله صنف باسم NewPost.php (نزعنا التعليقات للاختصار): <?php namespace App\Notifications; use Illuminate\Bus\Queueable; use Illuminate\Notifications\Notification; use Illuminate\Contracts\Queue\ShouldQueue; use Illuminate\Notifications\Messages\MailMessage; class NewPost extends Notification { use Queueable; public function __construct() { } public function via($notifiable) { return ['mail']; } public function toMail($notifiable) { return (new MailMessage) ->line('The introduction to the notification.') ->action('Notification Action', 'https://laravel.com') ->line('Thank you for using our application!'); } public function toArray($notifiable) { return [ ]; } } يمدّد الصنف NewPost الصنفَ Notification الذي يحوي التعليمات الضرورية للتعامل مع الإشعارات. تظهر الدالة المشيّدة Constructor وثلاث دوال أخرى: via: تعرّف القنوات التي نريد إرسال الإشعارات عبرها. توجد قناة البريد mail مبدئيا. تمكن إضافة قناة أخرى من تلك المتوفرة. يستخدم Laravel جميع القنوات المذكورة في المصفوفة المرجَعة، بمعنى؛ إن حددت مثلا القناتين mail وdatabase في المصفوفة فإن الإشعار سيُرسَل عبر البريد ويُخزَّن أيضا في قاعدة البيانات. toMail: هذه الدالة خاصّة بالتعامل مع قناة البريد الإلكتروني. تنشئ الدالة toMail كائنا من صنف MailMessage لتخصيص بريد إلكتروني. سنعود لهذا الصنف بعد قليل. toArray: إن حدّدت قناة للإشعارات في الدالة via دون أن تنشئ دالة خاصّة للتعامل معها فسيستدعي Laravel الدالة toArray. تجدر الإشارة إلى أن الدوال المخصّصة للتعامل مع قنوات الإشعارات تبدأ بـto متبوعة باسم القناة. مثلا toMail للبريد الإلكتروني (تأتي مبدئيا) وtoDatabase لتخصيص الإشعار عبر قناة قاعدة البيانات. نعدّل الصنف NewPost قليلا بحيث نمرّر للمشيّد معطى من نوع Post (نزعنا أجزاء الصنف التي لم يطرأ عليها تعديل): <?php // استدعاء الأصناف، أضفنا إليه الصنف Post use App\Post; class NewPost extends Notification { // أضفنا خاصيّة post إلى الصنف protected $post; public function __construct(Post $post) { $this->post = $post; } // بقية شفرة الصّنف } نعود إلى الدالة notify في المتحكم ونعدّلها لتصبح على النحو التالي: public function notify($user_id,$post_id) { $user = User::find($user_id); $post = Post::find($post_id); $user->notify(new NewPost($post)); } لا تنس استدعاء الصنف NewPost في المتحكم: use App\Notifications\NewPost; استدعينا الدالة notify من الكائن user$ ومررنا إليها صنفا جديدا من الإشعار NewPost. سنحتاج قبل تجربة إرسال الإشعار إلى ضبط البريد الإلكتروني في ملف النظام env.. ستجد في الملف عند فتحه الإعدادات التالية: MAIL_DRIVER=smtp MAIL_HOST=mailtrap.io MAIL_PORT=2525 MAIL_USERNAME=null MAIL_PASSWORD=null MAIL_ENCRYPTION=null يقترح Laravel مبدئيا موقع https://mailtrap.io الذي يوفر خدمة لمحاكاة إرسال بريد إلكتروني وعرضه. نحصُل بالتسجيل في الموقع على صندوق بريد للاختبار. ندخل إلى صندوق البريد (Demo inbox). ننسخ قيم Username وPassword ونضيفها إلى الإعدادات في ملف env. على النحو التالي: MAIL_DRIVER=smtp MAIL_HOST=mailtrap.io MAIL_PORT=2525 MAIL_USERNAME="be7c7d3972da27" MAIL_PASSWORD="5f445b7bdca027" MAIL_ENCRYPTION=null يمكننا الآن اختبار الإشعار بتشغيل خادوم التطبيق والذهاب إلى المسار http://localhost:8000/notify/1/2. إن نظرت في صندوق البريد على موقع mailtrap فستجد رسالة جديدة: لاحظ العنوان البريدي الذي يُوجّه إليه الإشعار medeyil@laravel.com. إن عدلت المسار الذي تطلُبه إلى التالي http://localhost:8000/notify/2/2 ونظرت في الإشعار الذي يصل إلى البريد فستجد أن المرسَل إليه To تبدّل إلى fbenziane@laravel.com الذي هو بريد المستخدم ذي المعرف 2. هل تساءلت كيف يعرف نظام الإشعارات البريد الإلكتروني الذي يجب إرسال الإشعار إليه، أي البريد الإلكتروني الخاصّ بالمستخدِم؟ تخصيص الإشعار عبر البريد الإلكتروني يمكن تطبيق الإشعارات على أي نموذج Eloquent في النظام، بشرط أن يستخدم النموذجُ السّمةَ Trait المسمّاة Notifiable. إن نظرنا إلى النموذج User الذي يأتي مبدئيا مع المشروع فسنلاحظ التالي: use Illuminate\Notifications\Notifiable; و use Notifiable; يتيح استخدام هذه السمة في النموذج إمكانية استدعاء الدالة notify: $user->notify(new NewPost($post)); التي تأخذ معطى عبارة عن كائن من صنف Notification. بالنسبة لكيفية معرفة نظام الإشعارات ببريد المستخدم فالإجابة هي أن كل قناة إشعار تتطلّب وجود خاصيّات Properties معيّنة في النموذج الذي يستدعي الدالة notify. في حالة قناة البريد الإلكتروني فإن الخاصيّة المنتظرة هي - منطقيا - عنوان البريد email. بالعودة إلى الصنف NewPost لاحظ دالة التعامل مع البريد الإلكتروني: public function toMail($notifiable) { return (new MailMessage) ->line('The introduction to the notification.') ->action('Notification Action', 'https://laravel.com') ->line('Thank you for using our application!'); } ترجع هذه الدالة كائنا من صنف MailMessage. إن تنبهت جيدا فستدرك أن العبارات الواردة في الشفرة أعلاه هي نفسها الموجودة في البريد المرسَل إلى المستخدم: الدالة line تدرج فقرة في بريد الإشعار. الدالة action تدرج زرًّا وتحدّد النص الذي يظهر على الزرّ ورابط الصفحة التي تزورها عند النقر على هذا الزرّ. توجد دوال أخرى لتخصيص الإشعار أكثر: subject لتخصيص موضوع البريد الإلكتروني. from لتحديد بريد المرسِل. attach لإضافة ملف مرفَق. priority لتحديد الأولوية (1 تعني أولوية قصوى). نخصّص في ما يلي البريد السّابق: public function toMail($notifiable) { return (new MailMessage) ->subject('New post: '. $this->post->title) ->line('Don\'t miss our new post ' .$this->post->title) ->action('View the post', 'https://laravel.com') ->line('Thank you for your visit!') ->from('hsoub@academy.com'); } نحصل بزيارة الرابط http://localhost:8000/notify/1/2 على النتيجة أدناه. بالنسبة لاسم التطبيق الذي يظهر في الإشعار فيمكن تعديله عن طريق التعليمة name في ملف الإعداد config/app.php. تأخذ التعليمة مبدئيا القيمة Laravel. إن أردت تخصيصا أكبر للبريد ومظهره فيمكنك ذلك بنشر قالب Blade الخاص بالبريد الإلكتروني للإشعار ومن ثم تخصيصه. نفذ الأمر التالي لنشر القالب: php artisan vendor:publish --tag=laravel-notifications ستجد القالب على المسار resources/views/vendor/notifications/email.blade.php؛ حيث يمكنك التعديل عليه بما تراه مناسبا.1 نقطة
-
تحدّثنا في بداية هذه السلسلة عن أن مشاريع إطار العمل Django تتبع بنية Model-View-Template (النموذج - العرض - القالب) وبعد أن تطرقنا في الجزء الثالث من هذه السلسلة إلى النماذج Models وآلية عملها، سنشرع في هذا الجزء بالحديث عن القسم الثاني من بنية المشاريع ألا وهو العروض Views. والعروض في Django هي صفحة ويب في تطبيق Django تؤدي وظيفة معينة وترتبط بقالب Template معين. فعلى سبيل المثال إن كان التطبيق الذي نعمل عليه عبارة عن مدونة، فإنه سيتضمن العروض التالية: الصفحة الرئيسية للمدونة، تعرض المقالات التي أضيفت مؤخرًا. صفحة المقالة، تعرض نص المقالة وتوفّر الرابط الدائم لها. أرشيف المدونة حسب السنوات، تعرض المقالات المنشورة في سنة معينة. أرشيف المدونة حسب الأشهر، تعرض المقالات المنشورة في شهر معين. أرشيف المدونة حسب الأيام، تعرض جميع المقالات المنشورة في يوم معين. حدث التعليق على المقالة، ويتحكم في عملية إضافة التعليقات على مقالة معينة. نرى مما سبق أن العروض تقوم بوظائف متعددة، فهناك عروض مسؤولة عن عرض المقالات إما باختيار المقالة المطلوبة من قبل المستخدم أو البحث عنها من خلال الأرشيف، وهناك عرض يتولى مسؤولية التحكم بعملية إضافة التعليقات في المدونة. سيتضمن تطبيق الاقتراعات الذي نعمل عليه ضمن هذه السلسلة العروض الأربعة التالية: صفحة الأسئلة الرئيسية index، والتي نعرض فيها آخر الأسئلة المضافة. صفحة تفاصيل السؤال detail، نعرض فيها نص السؤال، إلى جانب نموذج للتصويت. صفحة نتائج السؤال results، نعرض فيها نتائج التصويت على سؤال معين. حدث التصويت، نتحكم من خلاله بعملية التصويت على سؤال معين. ذكرنا في الدرس السابق أن اختيار العرض المناسب وتنفيذه في Django يتم بالاعتماد على المسار الذي يدخله المستخدم في شريط العناوين في المتصفح، إذ يرتبط كل عرض بمسار محدد ويتم تنفيذ العرض عندما يتطابق المسار الذي أدخله المستخدم مع أحد المسارات الموجودة في ملف urls.py، وقد قمنا بذلك بالفعل في الدرس السابق من هذه السلسلة. آلية عمل العروض تقتصر وظيفة العروض على القيام بأمرين اثنين: إرجاع كائن HttpResponse يتضمن محتوى الصفحة المطلوبة. إطلاق استثناء مثل Http404. والباقي عائد إليك، إذ يمكنك أن تجلب عددًا من السجلات من قاعدة البيانات باستخدام العروض، أو يمكنك استخدام نظام القوالب الخاص بـ Django أو أي نظام قوالب آخر، كما يمكنك إنشاء ملفات PDF أو XML أو إنشاء ملفات مضغوطة ZIP… الخ. عمليًا، يمكنك القيام بما تشاء وباستخدام أي مكتبة من مكتبات بايثون، وكل ما يحتاجه Django هو الكائن HttpResponse أو الاستثناء. لنقم الآن بكتابة عرض بسيط يعمل على جلب آخر خمسة أسئلة في قاعدة البيانات ويعرضها في المتصفح مفصولة عن بعضها البعض بفاصلة (,) ومرتبة حسب تاريخ النشر. توجه إلى polls/views.py ثم أضف الشيفرة التالية: from django.http import HttpResponse from .models import Question def index(request): latest_question_list = Question.objects.order_by('-pub_date')[:5] output = ', '.join([q.question_text for q in latest_question_list]) return HttpResponse(output) لنتحدث عن هذه الشيفرة بشيء من التفصيل: في السطر الأول قمنا باستيراد الكائن HttpResponse من وحدة django.http والصنف Question من ملف النماذج models.py الموجود في نفس المجلد الذي يحتوي الملف views.py، وذلك لنتمكن من الاستعلام عن الأسئلة الموجودة في قاعدة البيانات. بعد ذلك بدأنا بتعريف العرض وذلك من خلال إنشاء الدالة index. في كل دالة عرض يتم تمرير كائن HttpRequest والذي يأخذ عادة الاسم request. من الجدير بالذكر أنك لست مقيدًا بتسمية الدالة باسم معين لكي تؤدي العمل المطلوب، إذ يمكنك أن تسمي الدالة السابقة بأي اسم تشاء، ولكن ينصح بتسمية الدوال بأسماء واضحة يمكن من خلالها معرفة العمل الذي ستؤديه عند العودة إليها في وقت لاحق. يرجع العرض كائن HttpResponse يحتوي الردّ الذي قمنا بإنشائه والذي يتضمن نتيجة الاستعلام عن آخر خمسة أسئلة تم نشرها في الموقع، وذلك بواسطة الواجهة البرمجية الخاصة باستدعاء البيانات الخاصة بـ Django، والتي تحدثنا عنها في موضوع النماذج في Django. قمنا في الدرس السابق بربط العرض index بالمسار r’^$’، وهذا يعني أننا لسنا بحاجة إلى إدخال أي شيء في شريط العناوين سوى عنوان النطاق، وهو الخادوم المحلي الخاص بـ Django. ولمشاهدة مخرجات الدالة التي قمنا بكتابتها، توجّه إلى سطر الأوامر وقم بتشغيل خادوم Django من خلال الأمر التالي: python manage.py runserver افتح المتصفح ثم توجه إلى العنوان التالي: http://127.0.0.1:8000/ ربط العروض بالقوالب أعتقد أنّك لاحظت وجود مشكلة بسيطة في هذه الشيفرة، وهي أن تنسيق المخرجات من خلال إضافة وسوم HTML وتنسيقات CSS وغيرها من الأمور المرتبطة بواجهة الموقع العامة من خلال العروض ليس أمرًا عمليًّا على الإطلاق. هذا يعني أننا بحاجة إلى طريقة لفصل تصميم صفحة الويب عن الشيفرات المكتوبة بلغة بايثون، وهنا يأتي دور القوالب Templates، العنصر الثالث من بنية المشاريع في Django. والقوالب عبارة عن ملفات HTML عادية تتضمن وسوم HTML و تنسيقات CSS وشيفرات Javascript (سواء أكانت شيفرات عادية أم مكتبات مثل Jquery، Angular، React وغيرها)، ولكن الفارق الوحيد هو إمكانية استخدام محرك القوالب Template Engine الخاص بـ Django داخل هذه القوالب. لاستخدام القوالب في مشروعنا هذا، أنشئ مجلدًا باسم templates في مجلد polls، واعتمادًا على الإعدادات الافتراضية فإن Django سيبحث عن ملفات القوالب ضمن هذا المجلد. والآن في مجلد templates أنشئ مجلدًا آخر باسم polls وبداخل هذا المجلد أنشئ الملف index.html، وهكذا يكون مسار ملفنا هذا هو: polls/templates/polls/index.html. والآن يمكن الإشارة إلى هذا القالب باستخدام المسار: polls/index.html فقط. ولكن ما الداعي لإنشاء كل هذه المجلدات؟ في الواقع كان بالإمكان أن نضع الملف index.html في مجلد templates وحسب دون الحاجة إلى إنشاء مجلد polls آخر ضمنه، ولكن من غير المستحسن على الإطلاق القيام بذلك. السبب وراء هذا هو أن Django سيعتمد أول قالب يطابق اسمه الاسم المطلوب، وهذا يعني أنه لو وجد اسم القالب نفسه (index.html في مثالنا هذا) في تطبيق آخر فإنه لن يكون قادرًا على التمييز بينهما؛ لذا يستحسن دائمًا استخدام هذه الطريقة لضمان عدم تداخل القوالب بين التطبيقات المتعددة في المشروع الواحد. والآن أضف الشيفرة التالية إلى ملف index.html الذي أنشأته: {% if latest_question_list %} <ul> {% for question in latest_question_list %} <li><a href="/polls/{{ question.id }}/">{{ question.question_text }}</a></li> {% endfor %} </ul> {% else %} <p>الاقتراعات غير متوفرة حالياً.</p> {% endif %} سنتكلم عن محرك القوالب الخاص بـ Django وكل ما يتعلق به في الدرس القادم. بقي علينا ربط العرض index بالقالب index.html؛ لذا توجه إلى الملف polls/views.py وعدله بالشكل التالي: from django.http import HttpResponse from django.template import loader from .models import Question def index(request): latest_question_list = Question.objects.order_by('-pub_date')[:5] template = loader.get_template('polls/index.html') context = { 'latest_question_list': latest_question_list, } return HttpResponse(template.render(context, request)) في السطر الثاني من الدالة index قمنا بتحميل القالب الذي سيرتبط بهذه الدالة، وذلك من خلال الدالة get_template التابعة للوحدة loader التي قمنا باستيرادها في بداية الملف من الوحدة template. تأخذ الدالة get_template معاملًا وهو عبارة عن سلسلة نصية نحدّد من خلالها مسار القالب الذي نرغب في ربطه بالعرض. بعد ذلك قمنا بتعريف ما يسمى في Django بالسياق context وهو عبارة عن قاموس Dictionary يعمل على ربط المتغيرات التي سنستخدمها في محرك القوالب الخاص بـ Django - متمثلة بالمفتاح الخاص بالقاموس -، مع المتغيرات الموجودة في العرض - متمثلة بالقيمة المرتبطة بذلك المفتاح -. في الشيفرة السابقة، قمنا بربط المتغير latest_question_list في العرض بالمتغير latest_question_list في القالب index.html. وفي نهاية الشيفرة ترجع الدالة index كائن HttpResponse ولكن هذه المرة قمنا بتمرير الدالة render كمعامل لهذا الكائن، وقمنا بتمرير المتغير template والقاموس context كمعاملين لدالة render، والتي تعمل على دمج قالب معين مع السياق المحدد وتعيد كائن HttpRespons يتضمن ما سيعرض في القالب. توجه الآن من خلال المتصفح إلى العنوان التالي، بعد تشغيل الخادوم الخاص بـ Django: http://127.0.0.1:8000/polls/ سترى الآن قائمة نقطية تتضمن الأسئلة التي أضفناها في الدروس السابقة إلى قاعدة البيانات. اختصار عرض القوالب باستخدام الدالة render: إن الخطوات السابقة (تحميل القالب ثم تحديد سياق المتغيرات ثم إرجاع الكائن HttpResponse الذي يتضمن النتيجة التي سيعرضها القالب) شائعة جدًّا وتتكرر باستمرار، لذا يقدّم Django اختصارًا لهذه الخطوات باستخدام الدالة render() التابعة لحزمة django.shortcuts والتي تتضمن عددًا من الدوال التي تختصر بعض الخطوات التي تتكرر باستمرار في Django. قم بتعديل الملف polls/views.py ليصبح بالشكل التالي: from django.shortcuts import render from .models import Question def index(request): latest_question_list = Question.objects.order_by('-pub_date')[:5] context = {'latest_question_list': latest_question_list} return render(request, 'polls/index.html', context) المعامل الأول في دالة render هو كائن request الذي مررناه كمعامل للدالة index، أما المعامل الثاني فهو اسم القالب ومساره على هيئة سلسلة نصية، أما المعامل الثالث فهو قاموس سياق المتغيرات التي نرغب في تمريرها من العرض إلى القالب، وهو معامل اختياري. تعيد هذه الدالة كائن HttpResponse يتضمن ما سيتم عرضه في القالب المحدّد وباستخدام السياق المحدّد. لاحظ أننا لم نعد بحاجة إلى استيراد دالة loader وكائن HttpResponse في بداية الملف. إطلاق الاستثناء Http404 لننتقل الآن إلى دالة العرض المسؤولة عن سرد تفاصيل السؤال الذي يختاره المستخدم؛ لذا توجه إلى الملف polls/views.py ثم أضف السطر التالي في بداية الملف: from django.http import Http404 ثم عدّل الدالة detail لتصبح بالشكل التالي: def detail(request, question_id): try: question = Question.objects.get(pk=question_id) except Question.DoesNotExist: raise Http404("السؤال المطلوب غير موجود.") return render(request, 'polls/detail.html', {'question': question}) قمنا بتمرير معامل جديد في الدالة detail وهو question_id، وهذا المعامل هو المتغير الذي قمنا بتعريفه في ملف المسارات urls.py في الدرس السابق، ضمن المسار المرتبط بهذه الدالة. يحمل هذا المتغير الرقم الذي سيدخله المستخدم في شريط العناوين والذي سيلتقطه Django بواسطة التعابير النظامية Regular expressions ويسنده إلى المتغير question_id. تبدأ الدالة بالاستعلام عن السؤال الذي يحمل المفتاح الأساسي primary key - يختصر Django اسم هذا المفتاح بالحرفين pk - الذي يطابق قيمة المتغير question_id وإسناد النتيجة إن وجدت إلى المتغير question. وفي حالة عدم وجود هذا السؤال يتم إطلاق الاستثناء Http404 ليُعلم المستخدم بعدم وجود السؤال الذي قام بطلبه. والآن نحن بحاجة إلى القالب detail.html لنتمكن من مشاهدة السؤال المطلوب؛ لذا قم بإنشاء هذا الملف في مجلد templates/polls. سنكتفي هنا بإضافة السطر التالي في هذا الملف، للتأكد من عمل الشيفرة: {{ question }} اختصار خطوات الاستعلام وإطلاق الاستثناء Http404 مرة أخرى، فإن الخطوات السابقة (الاستعلام باستخدام الدالة get وإطلاق الاستثناء Http404) تتكرر باستمرار، لذا يقدّم Django دالة بديلة تختصر هذه العملية، وكما هو متوقع فهذه الدالة موجودة في حزمة django.shortcuts، لذا سنقوم باستيرادها بالشكل التالي مع الدالة render: from django.shortcuts import get_object_or_404, render يمكن الآن استخدام الدالة get_object_or_404() بالشكل التالي: def detail(request, question_id): question = get_object_or_404(Question, pk=question_id) return render(request, 'polls/detail.html', {'question': question}) المعامل الأول في الدالة get_object_or_404() هو اسم النموذج الذي نرغب في الاستعلام داخله، أما المعامل الثاني فهو مجموعة من معاملات الكلمة المفتاحية والتي تقوم الدالة بتمريرها إلى دالة get() الخاصة بواجهة Django البرمجية للاستعلام في قواعد البيانات. في حالة عدم وجود الكائن المطلوب تطلق الدالة الاستثناء Http404. يقدّم Django كذلك دالة get_list_or_404() والتي تعمل بنفس الطريقة باستثناء أنّها تستخدم الدالة filter() بدلًا من get()، وتطلق الدالة الاستثناء Http404 في حال عدم وجود القائمة المطلوبة. والآن توجّه إلى العنوان التالي في المتصفح بعد تشغيل خادوم Django، ولاحظ النتيجة: (http://127.0.0.1:8000/polls/1) حاول تغيير رقم السؤال لإطلاق الاستثناء Http404. خاتمة تعرفنا في هذا الدرس على العنصر الثاني من بنية المشاريع في Django ألا وهي العروض، وتعرفنا كذلك على طريقة ربطها بالقوالب والتي تمثّل العنصر الثالث من بنية المشاريع في إطار العمل هذا. وسنتطرق في الفصل القادم بمزيد من التفصيل إلى القوالب وآلية عملها وسنتعرف على محرك القوالب الخاص بـ Django وما يتضمنه من متغيرات ووسوم وغيرها، وسنتعرّف كذلك على العروض المستندة إلى الأصناف والعروض العامة Generic Views. المصادر: توثيقات Django1 نقطة
-
تعرفنا في الأجزاء الثلاثة السابقة من هذه السلسلة على إطار العمل Django وكيفية تنصيبه وبدأنا بالفعل بإنشاء تطبيق الاقتراعات من خلال هذا الإطار، وتعرفنا بشكل مبسط على المسارات والعروض وطريقة ربطها ببعض، كما تعرفنا كذلك على طريقة التعامل مع قواعد البيانات باستخدام النماذج وكيفية تهجير قواعد البيانات وطرق الاستعلام المختلفة المتوفرة في Django. وفي الجزء الرابع من هذه السلسلة سنتكلم عن المسارات URLs وآلية عملها بصورة أوسع، وسنتطرق في حديثنا إلى كيفية الاستفادة من التعابير النظامية Regular expressions لجعل مسارات تطبيقنا (تطبيق الاقتراعات) أكثر ترتيبًا ووضوحًا. من المؤكّد أنّك وأثناء تجوالك في مواقع الإنترنت قد شاهدت روابط كهذه: “ME2/Sites/dirmod.asp?sid=&type=gen&mod=Core+Pages&gid=A6CD4967199A42D9B65B1B” هذا الشكل من الروابط غير مرغوب فيه على الإطلاق في Django، إذ يستخدم هذا الإطار مفهوم أنماط المسارات URL patterns لإظهارها بصورة مرتبة وواضحة وذات دلالة في نفس الوقت. والمقصود بأنماط المسارات بكل بساطة هو أن تمتلك المسارات نسقًا معينًا، مثل: /newsarchive/<year>/<month>/ هذا يعني أنه للوصول إلى أرشيف الأخبار في هذا الموقع، ينبغي كتابة كلمة newsarchive ثم كتابة السنة المطلوبة يليها الشهر المطلوب، وما سيفعله Django هنا هو البحث ضمن مسارات التطبيق عن أي مسار يطابق ما أدخله المستخدم، لتفعيل العرض المرتبط بذلك المسار، ويعتمد Django على التعابير النظامية Regular Expression لإجراء عملية البحث، وسنتكلم عن هذا بشيء من التفصيل بعد قليل. مسارات تطبيق الاقتراعات سيؤدي تطبيق الاقتراعات الذي نعمل على إنشائه المهام التالية: صفحة رئيسية index تعرض عددًا من الأسئلة المطروحة في الموقع. صفحة تفاصيل السؤال detail تعرض سؤالًا معيّنًا إلى جانب الأجوبة المتاحة لهذا السؤال للتصويت. صفحة نتائج results تعرض النتائج المتعلقة بسؤال معين. عملية التصويت، والتي يتم من خلالها التصويت على جواب معين مرتبط بسؤال معين. وكما ذكرنا في الدروس السابقة فإنّ عملية إرسال الطلبات وتلقي الإجابة عليها هي مهمة العروض؛ لذا سننشئ أربعة عروض يختص كل منها بمهمة محددة من المهام الأربعة الخاصة بالتطبيق. افتح ملف polls/views.py في محرر النصوص المفضل لديك، ثم أضف الشيفرة التالية بعد دالة index التي أضفناها إلى هذا الملف في الدرس الثاني. def detail(request, question_id): return HttpResponse("هذا هو السؤال %s." % question_id) def results(request, question_id): response = "هذه نتائج السؤال %s." return HttpResponse(response % question_id) def vote(request, question_id): return HttpResponse("أنت تصوت على السؤال %s." % question_id) الدالة الأولى هي دالة detail وهي المسؤولة عن عرض تفاصيل السؤال الذي يرغب المستخدم التصويت عليه، أما الدالة الثانية results فمسؤولة عن عرض نتائج التصويت على سؤال معين يختاره المستخدم، أما الدالة الثالثة vote فتتحكم في عملية التصويت التي يقوم بها المستخدم. ستؤدي هذه الدوال في الوقت الحاضر مهمّة واحدة بسيطة وهي عرض عبارة خاصّة بكل دالّة على المتصفح مع إضافة معرّف السؤال الذي سيختاره المستخدم، وذلك للتعرف على آلية عمل المسارات في Django، وسنعود إلى هذه العروض في الدروس القادمة وبشكل تفصيلي لإضافة الشيفرة التي ستعطي النتيجة الفعلية المطلوبة من كل دالة من هذه الدوال. لعرض نتائج هذه الدوال على المتصفح، سنحتاج إلى ربطها بمسارات خاصة، تمامًا كما فعلنا في الدروس السابقة، ولكننا سنستخدم التعابير النظامية هذه المرة لتعيين نمط المسار الذي نرغب بربطه مع كل دالة في ملف العروض. عزل مسارات التطبيق عن مسارات المشروع قبل أن نبدأ عملية ربط المسارات بالعروض، سنتطرق إلى إحدى الممارسات التي يُنصح اتباعها بشدة عند تطوير التطبيقات باستخدام إطار العمل Django، ألا وهي عزل مسارات التطبيق عن مسارات المشروع. تتمتع تطبيقات Django بعدم ارتباطها بالمشروع الذي يحتويها، بمعنى أنّه يمكنك استخدام تطبيق الاقتراعات هذا في أي مشروع ترغب به، دون الحاجة إلى إجراء أي تعديل في بنية وهيكلية التطبيق. وتحقيق هذا الأمر لا يتطلب سوى عزل المسارات الخاصة بالتطبيق في ملف منفصل، ثم الإشارة إلى هذا الملف في ملف المسارات الرئيسي الخاص بالمشروع لتصبح مسارات التطبيق الخاصة جزءًا من مسارات ذلك المشروع. ولعزل مسارات تطبيق الاقتراعات عن المسارات الرئيسية للمشروع، توجّه إلى ملف mysite/urls.py وعدّله ليصبح بالشكل التالي: from django.conf.urls import include, url from django.contrib import admin urlpatterns = [ url(r'^polls/', include('polls.urls')), url(r'^admin/', admin.site.urls), ] قمنا في السطر الأول باستيراد الدالة include والتي ستعمل على تضمين المسارات الموجودة في ملف polls/urls.py وربطها بالمسار polls/، كما هو موضح في العنصر الأول من قائمة urlpatterns. فعلى سبيل المثال، لو طلب المستخدم العنوان mypolls/ في المتصفح يبدأ إطار العمل في البحث عن هذه الكلمة في ملف urls.py الخاص بالمشروع، وفي حالة عدم العثور عليها تظهر صفحة خطأ للمستخدم تفيد بعدم وجود هذا العنوان. وفي حالة استخدام الدالة include يضيف Django إلى مجال بحثه الملف الذي تشير إليه هذه الدالة، بمعنى أنه لو طلب المستخدم العنوان polls/3/ مثلًا فسيتم البحث أولًا عن عبارة polls في ملف mysite/urls.py الخاص بالمشروع الرئيسي، وما أن يتم العثور على العبارة المطلوبة تبدأ الدالة include بالعمل وتبدأ عملية البحث عن العبارة التالية لـ polls (الرقم 3 في مثالنا هذا) في ملف polls/urls.py الخاص بالتطبيق والذي تشير إليه الدالة. ولعزل مسارات التطبيق في ملف منفصل، توجّه إلى مجلد polls وأنشأ فيه ملفًّا جديدًا باسم urls.py، ثم أضف فيه الشيفرة التالية: from django.conf.urls import url from . import views urlpatterns = [ # ex: /polls/ url(r'^$', views.index, name='index'), # ex: /polls/5/ url(r'^(?P<question_id>[0-9]+)/$', views.detail, name='detail'), # ex: /polls/5/results/ url(r'^(?P<question_id>[0-9]+)/results/$', views.results, name='results'), # ex: /polls/5/vote/ url(r'^(?P<question_id>[0-9]+)/vote/$', views.vote, name='vote'), ] لاحظ أن بنية هذا الملف مشابهة بشكل كبير للملف mysite/urls.py، حيث يتم استيراد الدالة url في بداية الملف، كما أن قائمة المسارات urlpatterns مماثلة للقائمة الموجودة في ملف mysite/urls.py. يعمل السطر الثاني في الشيفرة السابقة على استيراد ملف العروض views.py والموجود في مجلد polls والذي يضم في الوقت نفسه ملف المسارات هذا، لذا يمكن اختصار اسم المجلد باستخدام النقطة .. كيف تعمل المسارات في Django يستخدم Django المسارات كوسيلة للربط بين العنوان الذي يدخله المستخدم في شريط العناوين الخاص بالمتصفح وبين العروض التي تؤدي وظائف مختلفة ومتنوعة، فعندما يدخل المستخدم عنوانًا معينًا في شريط العناوين يبدأ Django بالبحث ضمن المسارات المتوفرة لديه في ملفات urls.py - كما ذكرنا قبل قليل - عن أي نمط يطابق المسار المدخل، فإن حصل تطابق بين العنوان الذي أدخله المستخدم وبين أحد المسارات ينفّذ Django العرض المرتبط بذلك المسار مباشرة. أما وسيلة البحث التي يستخدمها Django فهي التعابير النظامية، وهي عبارة عن سلسلة من الرموز التي تكوّن نمطًا معيّنًا يستعمل للبحث في النصوص (المسارات في حالتنا هذه) عن أجزاء تطابق هذا النمط، وتتألف سلسلة الرموز هذه من مجموعة من الحروف أو الأرقام التي تساعد في البحث عن كلمة معينة أو عبارة أو رقم معين، وإلى جانب ذلك يمكن استخدام عدد من الرموز الخاصة التي تحمل دلالات معينة في التعبيرات النظامية مثل ^، $، ؟ وغيرها. المعامل regex والتعابير النظامية تمتلك دالة url أربعة معاملات، اثنان منها معاملات إلزامية وهما regex وview واثنان اختياريان هما kwargs و name. والمعامل regex في دالة url عبارة عن سلسلة نصية خام تتضمن تعبيرًا نظاميًا، يستخدمه Django في مطابقة العناوين المدخلة من قبل المستخدم مع المسارات المتوفرة في ملفات urls.py. لتوضيح كيفية استخدام التعابير النظامية في Django سنبدأ أولًا بدالة url في ملف mysite/urls.py: url(r'^polls/', include('polls.urls')), لاحظ أن المعامل الأول يبدأ بالرمز ^، وهو أحد الرموز الخاصة في التعابير النظامية، ويشير إلى وجوب ورود الكلمة التي تلي هذا الرمز في بداية الجملة، وفي حالتنا هذه يتم البحث عن العبارات التي تبدأ بـ polls/، وهذا يعني أن العبارات polls/30 و polls/q=44 و polls/polls/polls/ و polls/sport/football/worldcup/2014 تكون كلها مطابقة لهذا النمط، إذ أنّ العبارات كلها تبدأ بـ polls/. عند استخدام الدالة include في هذا المسار، يبدأ Django بالبحث عن العبارات التي تبدأ بـ polls/ في ملف mysite/urls.py مضافًا إليها كل العبارات الموجودة في ملف polls/urls.py. يستخدم الرمز الخاص $ للإشارة إلى وجوب ورود الكلمة التي تسبق هذا الرمز في نهاية الجملة. لاحظ المثال التالي: url(r'^polls/$', views.index, name='index'), سيبحث Django في هذه الحالة عن العبارات التي تكون فيها كلمة polls/ في بداية ونهاية الجملة في الوقت ذاته، بمعنى أن العبارات polls/30 و polls/q=44 و polls/polls/polls/ و polls/sport/football/worldcup/2014 لن تكون مطابقة لهذا النمط، إذ أن كلمة polls/ تقع في بداية هذه الجمل، ولكنها ليست في نهايتها، أما العبارة polls/polls/polls فليست مطابقة لأن الكلمة المطلوبة ليست في بداية ونهاية الجملة في الوقت ذاته، فكلمة polls/ الأولى تقع في بداية الجملة وليست في نهايتها، وكلمة polls/ الأخيرة موجودة في نهاية الجملة وليست في بدايتها، وبهذا لا يحصل التطابق. لنرفع الآن من مستوى تعقيد السلاسل المستخدمة كتعابير نظامية، ونأخذ دالة url التي تربط المسار بالعرض detail في ملف polls/urls.py: url(r'^(?P<question_id>[0-9]+)/$', views.detail, name='detail'), يستخدم Django الأقواس لالتقاط النص الذي يطابق النمط المستخدم في التعابير النظامية، ويمكن إسناد هذه القيمة إلى متغير بالشكل التالي: ?P<variable_name>، وفي مثالنا هذا سيتم إسناد القيمة المطابقة للتعبير النظامي إلى المتغير question_id. يتألف التعبير [0-9]+ من جزأين، الأول هو [0-9] ويطابق الأعداد التي تضم الأرقام من 0 إلى 9 حصرًا ولن يحدث التطابق في حال وجود أي حرف حتى مع وجود الأرقام، أما علامة + فهي إحدى الرموز الخاصة بالتعابير النظامية والتي تعني تكرار الأرقام مرة واحدة أو أكثر. هذا يعني أن Django سيبحث عن أي عبارة تبدأ بأي عدد (مثلًا: 3، 20، 4003 تطابق النمط، لكن abc، 3b2، ac3 لن تطابق النمط)، وفي حال مطابقة النمط لعبارة معينة سيتم إسنادها إلى المتغير question_id المستخدم في دالة detail الموجودة في ملف polls/views.py. للتأكد من ذلك، قم بتشغيل الخادوم الخاص بـ Django، من خلال سطر الأوامر، ثم أدخل العنوان التالي في المتصفح، ولاحظ النتيجة: http://127.0.0.1:8000/polls/33/ ما حدث هنا، هو أنك بعد أن أدخلت العنوان السابق في المتصفح، بدأ Django في البحث في ملف mysite/urls.py عن أي نمط يطابق العنوان المدخل، وبعد أن وجد أن النمط ^polls/ مطابق لهذا العنوان، بدأ المعامل الثاني للدالة url بالعمل والذي يتضمن الدالة include التي توجّه Django للبحث مرة أخرى عن العبارات التي تلي الكلمة polls/ ضمن العنوان المدخل، وتتم عملية البحث في الملف الذي تشير إليه الدالة وهو polls/urls.py، وبعد أن وجد Django أن النمط [0-9]+ مطابق لـ 33 بدأ المعامل الثاني للدالة url enter code hereبالعمل وهو تنفيذ العرض المرتبط بهذا المسار (detail) والموجود في ملف views.py. جرب تغيير الرقم (33) إلى أرقام أخرى، كذلك جرب كتابة حروف بدلًا من الأرقام ولاحظ النتائج. جرّب الآن تعديل العنوان إلى الشكل التالي، ولاحظ النتيجة: http://127.0.0.1:8000/polls/33/results/ يوضح الجدول التالي بعض التعابير النظامية والأنماط الناشئة من هذه التعابير: التعبير النظامي النمط [A-Z]+ الحروف الإنكليزية الكبيرة مع تكرارها لمرة واحدة على الأقل [A-Za-z]+ الحروف الإنكليزية الكبيرة والصغيرة مع تكرارها لمرة واحدة على الأقل [0-9]+ جميع الأرقام مع تكرار الرقم لمرة واحدة على الأقل \w يطابق هذا النمط أي كلمة \d يطابق هذا النمط أي رقم [A-Za-z0-9]+ يطابق هذا النمط جميع الحروف الإنكليزية إضافة إلى الأرقام للاطلاع بشكل أكبر على التعابير النظامية والرموز المستخدمة فيها، يمكن زيارة المواقع التالية: * Regular-Expressions.info * Regexr، يتيح هذا الموقع تجربة التعابير النظامية بصورة مباشرة في المتصفح. المعامل name المعامل name عبارة عن سلسلة نصية يمكن من خلالها تحديد اسم خاص بالمسار، وسنستفيد من هذا الاسم لاحقًا في الإشارة إلى المسار عند التعامل مع القوالب في الدروس القادمة. خاتمة تعرفنا في هذا الدرس على المسارات في إطار العمل Django وآلية عملها وكيفية الاستفادة من التعابير النظامية في إنشاء المسارات وتمرير المتغيرات إلى العروض. درسنا القادم سيكون حول العروض وأنواعها وآلية عملها، وسنبدأ بكتابة العروض المفصلة الخاصة بتطبيق الاقتراعات، وربطها بالمسارات. المصدر: توثيقات Django1 نقطة
-
عندما اذهب الى خدمات غير الموجوده سيكون هناك اشخاص يعرضون كبونات1 نقطة
-
السلام عليكم اخواني .. رجاء من الخبراء ما هي أفضل احجام التجاوب على الحاسوب وليس الهواتف فأحجام الهواتف معروفة ... لأني دائما في تصميماتي اعتمد على مساحة 1024 بكسل كـ أكبر حجم وأنا الان أصمم قالب لعميل طلبه يحتاج إلى مساحة أكبر فاعتمدت أن تكون أكبر مساحة هي 1280 بكسل فبرجاء أريد معرفة التدرج التجاوبي بين هاتين المساحتين ؟؟ مثال لكي تفهمون ما أريد .. المساحة في الهواتف بين 768 و 568 بكسل هي 640بكسل فأريد معرفة حجم التدرج ما بين 1280،1024 وشكرا لكم مقدما وبرجاء الاهتمام للضرورة ( من كتم علماً الجمه الله لجاماً من نار )1 نقطة
-
ابحث عنه اخي العزيز في خمسات قم باضافة موضيع في " طلبات الخدمات غير الموجودة " في خمسات https://khamsat.com/community/requests1 نقطة
-
وجود ميثاق عمل مشترك ببنود مُرضية لجميع أطرافه أمر هام يجب الانتباه إليه وتطبيقه علمًا بأنه يمكن التفاوض بشأن هذه البنود حتى يصل جميع أطراف هذا العمل إلى صيغة توافقية تؤدي في النهاية إلى الوصول إلى عمل يُرضي الله ثم أطراف هذا العمل المشترك.1 نقطة
-
و عليكم السلام تأكد من وجود السطر ()session_start أعلى الصفحة قبل إرسال أي بيانات <? ;()php session_start?> <!DOCTYPE html PUBLIC > <html> ....1 نقطة
-
سأقوم بالتطبيق قريبا ان شاء الله وفي انتظار باقي الدروس1 نقطة
-
كيف وأين أجد الفكرة المناسبة لتطبيقها؟ يتكرر هذا السؤال كثيرا من طرف الراغبين في دخول عالم المبادرة وريادة الأعمال. بداية أرى أن قرار التحول إلى رائد أعمال هو قرار بعدي يأتي بعد الاحتكاك باحتياج معين غير مشبع في السوق، وليس قرارا قبليا يتخذه الشخص قبل إيجاد فكرة يشتغل عليها، كأن يستيقظ صباحا ويقول بأنه قرر أن يصبح رائد أعمال. كلا، الأمر لا يتم بهذا الشكل، وريادة الأعمال ليست وظيفة.. إنها أسلوب حياة. عودة إلى موضوع الأفكار. كتب Kapil Kale المؤسس الشريك لـ GiftRocket مقالا حدد فيه أربعة مبادئ توجيهية لمساعدة رواد الأعمال على انتقاء الأفكار المناسبة لمشروعهم الجديد. أرى أن المبدأ الأول هو الأهم على الإطلاق وهو يركز على ضرورة أن تحقق الفكرة هدفا واحدا على الأقل من هذه الأهداف الثلاث: (أ) تبسيط المهام الصعبة. مثلا خدمة داك واك لإدارة ترجمة المواقع تجعل مهمة توفير المواقع بلغات متعددة أمرا ميسورا. (ب) إتاحة بدائل رخيصة للأشياء الغالية. مثلا مواقع الشراء الجماعي مثل جونابت تتيح الحصول على خدمات ومنتجات كثيرة بأسعار مخفضة، وشركات تقديم الاستضافة السحابية مثل أمازون توفر خدمات الاستضافة بأسعار زهيدة نسبيا مقارنة مع الاستضافات العادية. (ج) توفير أشياء مسلية. مثلا المشاريع القائمة على الألعاب مثل لعبة بيردي نم نم، مشاريع الموسيقى وبصفة عامة مشاريع المحتوى. الآن من أين ستأتي بالفكرة المناسبة؟ حدد قائمة بالأشياء التي تستخدمها والتي لا تلبي احتياجاتك بشكل سليم: الحياة مليئة بالخدمات، الأدوات والمنتجات التي لا تلبي احتياجاتنا بشكل سليم، وأحيانا بدل أن تبسط أسلوب حياتنا تعقده أكثر. هل بإمكانك جعل تلك الأشياء تعمل بشكل مختلف وأفضل؟راقب مشترياتك: هل تصرف الكثير على شراء شيء معين؟ مراقبة فواترك قد تساعدك على اكتشاف مشتريات معينة عليها إقبال كبير، ويمكنك أن توفرها بشكل مختلف أو سعر أرخص.ما المشاكل التي تواجهها في عملك؟ كثير من رواد الأعمال كانوا ذات يوم مجرد موظفين عاديين في شركات أخرى، لكنهم صادفوا -أو كانوا مضطرين للتعايش مع- مشاكل ما دون حل، تعرقل الانتاجية، فسهروا الليالي لإيجاد حلول لتلك المشاكل، ثم تركوا الوظيفة لتأسيس شركاتهم الخاصة لتقديم تلك الحلول. الحياة مليئة بمثل هذه الفرص، سواء في الشركات، الجامعات أو أي مكان آخر. لا تنسى بأن الحاجة أم الاختراع.أخيرا، إليكم هذه القائمة ببعض الأفكار التي تقترحها حاضنة Ycombinator على المبادرين.1 نقطة