لوحة المتصدرين
المحتوى الأكثر حصولًا على سمعة جيدة
المحتوى الأعلى تقييمًا في 10/29/16 في كل الموقع
-
بعد أن تعرفنا في الدرس الأول على طريقة تثبيت Django وإنشاء مشروعنا الأول فيه، سنشرع في هذا الدرس في إنشاء تطبيقنا الأول والذي سيكون عبارة عن موقع بسيط للاقتراعات يتكون من قسمين: القسم الأول: واجهة يمكن للمستخدم أن يطلع من خلالها على الأسئلة المطروحة واختيار الإجابة التي يرغب فيها. أما القسم الثاني: لوحة تحكم يمكن من خلالها إضافة الأسئلة وتعديلها وحذفها وإضافة الأجوبة وغير ذلك من الأمور. المشاريع Projects والتطبيقات Applications قبل أن ندخل في تفاصيل إنشاء تطبيق الاقتراعات، لا بأس في الحديث بشكل موجز عن مفهومي "المشروع" Project و"التّطبيق" Application في Django. يمثّل المشروع تطبيق الويب الذي يتم إنشاؤه بواسطة Django، ويتم تعريفه من خلال ملف الإعدادات Settings، فكما رأينا في الدرس السابق فبعد تنفيذ الأمر: django-admin startproject mysite تم إنشاء حزمة بايثون تحتوي على ملفات settings.py و urls.py و wsgi.py، وعادة ما تتوسع هذه الحزمة بإضافة المزيد من الملفات مثل ملفات CSS والقوالب وما إلى ذلك من الأمور التي لا تكون مرتبطة بتطبيق معيّن. وعادة ما يكون مجلّد المشروع هذا (المجلد الذي يحتوي على الملف manage.py) حاويًا للتطبيقات التي يتم إنشاؤها بشكل مستقل، وهذه التطبيقات ما هي إلا حزم بايثون تعمل على تقديم بعض الخصائص وتؤدي بعض المهام، ويمكن استخدام هذه التطبيقات في مشاريع متعددة، وهذا ما يسمى بمبدأ قابلية إعادة الاستخدام re-usability. إنشاء تطبيق الاقتراعات ملاحظة: ابتدءًا من هذا الدرس فإن عبارة "مجلد المشروع" تعني المجلد الذي يحتوي على ملف manage.py. توجّه في سطر الأوامر إلى مجلد المشروع ثم اكتب الأمر التالي: python manage.py startapp polls يمكن الحصول على نفس النتيجة من خلال الأمر التالي: django-admin startapp polls بعد تنفيذ الأمر ستجد أنّ إطار العمل قد أنشأ مجلدًا جديدًا يحمل الاسم polls، ويتضمن عددًا من الملفات نستعرضها بشكل مختصر: init__.py__: هذا الملف مشابه للملف الموجود في مجلد المشروع، وهو ملف فارغ يعني وجوده أن هذا المجلد هو حزمة من حزم بايثون. admin.py: يمكن من خلال هذا الملف إدارة وتخصيص لوحة التحكم والتي تأتي جاهزة مع التطبيق. apps.py: يمكن من خلال هذا الملف إعداد التطبيق configuration لاستخدامه في مشاريع أخرى. models.py: سيتضمن هذا الملف النماذج التي يتعامل التطبيق معها، والتي تكون مسؤولة عن إنشاء جداول قواعد البيانات. tests.py: يمكن من خلال هذا الملف إجراء الاختبارات Tests على التطبيق. views.py: تضاف في هذا الملف العروض المسؤولة عن تحديد البيانات والمعلومات التي سيتم عرضها على المتصفح، وهي كذلك صلة الوصل بين المسارات والقوالب. مجلد migrations: سيستقبل هذا المجلد الملفات الناشئة عن عملية تهجير قاعدة البيانات. إعدادات المشروع يحتوي مجلد المشروع على ملف الإعدادات settings.py، وهو عبارة عن ملف بايثون يحتوي جميع الإعدادات الخاصة بالمشروع، وسنستعرض بعض محتويات هذا الملف بشكل موجز. BASE_DIR: متغير نصّي يقدّم مسار المجلد الأساسي للمشروع، ويمكن الاستفادة من هذا المتغير في تحديد مسارات المجلدات التي تحتوي على القوالب أو الملفات الساكنة وغيرها، وسنتعرف على طريقة استخدامه عند الحديث عن القوالب. SECRET_KEY: عبارة عن سلسلة نصية من حروف ورموز عشوائية يمكن الاستفادة منها في حماية التطبيق. DEBUG: متغير من نوع bool، ويمكن من خلاله التحكم في وضع التنقيح Debugging، حيث تظهر معلومات مفيدة عند حدوث الأخطاء، ولكن ينصح بتغيير قيمته إلى False عند نقل المشروع إلى بيئة الإنتاج. INSTALLED_APPS: عبارة عن قائمة تتضمن التطبيقات التي سيضمها المشروع الحالي، ويمكنك أن تلاحظ وجود عدد من التطبيقات المثبتة بشكل مسبق، مثل إدارة لوحة التحكم admin، والاستيثاق auth، والجلسات sessions وغيرها. TEMPLATES: عبارة عن قائمة تتضمن إعدادات القوالب المستخدمة في المشروع، وما يهمنا فيها هو العنصر DIRS والذي يتم من خلاله تعيين المسارات التي تحتوي على ملفات القالب. DATABASES: قائمة أخرى مسؤولة عن تحديد المعلومات اللازمة للتعامل مع قواعد البيانات، وسنتطرق إليها عند الحديث عن النماذج Models والاتصال بقواعد البيانات. LANGUAGE_CODE: يمكن من خلال هذا المتغير تحديد لغة واجهة لوحة التحكم، والإعداد الافتراضي هنا هو اللغة الإنكليزية، ولكن Django يدعم العديد من اللغات ومن ضمنها العربية، وإن كنت ترغب في استخدام اللغة العربية في عرض عناصر لوحة التحكم، فيمكنك تغيير قيمة هذا المتغير بالشكل التالي: LANGUAGE_CODE = 'ar' TIME_ZONE: يمكن من خلال هذا المتغيير تعيين المنطقة الزمنية التي سيستخدمها Django في دوال الوقت والتاريخ. ويمكن استبدال هذه القيمة حسب الرغبة. STATIC_URL: في هذا المتغير يتم تحديد مسار المجلد الذي يحتوي على الملفات الساكنة وهي ملفات CSS و Javascript والخطوط والصور وغيرها. كتابة العرض الأول العرض View عبارة عن دالة مكتوبة بلغة Python (أو صنف كما سنرى في الدروس اللاحقة) يمكن تلخيص عملها ببساطة في أنها تأخذ الطلبات Requests التي يرسلها العميل وتقوم بإرجاع الإجابة response والتي يمكن أن تكون على هيئة شيفرة بصيغة HTML، أو إعادة توجيه لصفحة أخرى، أو صفحة خطأ 404، أو ملف XML، أو صورة أو أي شي آخر. لنبدأ الآن بكتابة العرض الأول في مشروعنا، وللقيام بذلك افتح ملف polls/view.s.py في محرر النصوص المفضّل لديك، ثم امسح محتوياته واكتب الشيفرة التالية: from django.http import HttpResponse def index(request): html = "مرحبًا بك في تطبيق الاقتراعات، هذه هي الصفحة الرئيسية." return HttpResponse(html) في السطر الأول من هذه الشيفرة قمنا باستيراد الصنف HttpResponse من وحدة django.http، وهو المسؤول عن التعامل مع الاستجابة التي ترد على الطلب الذي أرسلناه إلى الخادوم من خلال الدالة index، وذلك عن طريق تمرير المعامل request عند تعريف الدالة. ستقوم هذه الدالة بإعادة العنصر HttpResponse والذي يحتوي على الإجابة، وهي في مثالنا هذا عبارة عن سلسلة نصية بسيطة. ملاحظة: في حال عدم ظهور الأحرف العربية بشكل صحيح، أضف السطر التالي إلى بداية ملف views.py: # -*- coding:utf8 -*- لنتمكن من مشاهدة النتيجة على المتصفح، يجب أن نربط هذا العرض بمسار معين؛ وللقيام بذلك توجه إلى الملف mysite/urls.py وعدّل محتوياته لتصبح بالشكل التالي: from django.conf.urls import url from django.contrib import admin from polls import views urlpatterns = [ url(r'^admin/', admin.site.urls), url(r'^polls/', views.index), ] يتضمن هذا الملف جميع المسارات التي سنستخدمها في المشروع، وهو بمثابة جدول لمحتويات الموقع. في البداية قمنا باستيراد محتويات ملف views.py الموجود في مجلد polls من خلال الشيفرة التالية: from polls import views من خلال هذه الشيفرة يمكنك أن تلاحظ أن Django يتعامل مع المجلد polls باعتباره حزمة من حزم بايثون، وذلك لاحتواءه على ملف init__.py__ كما ذكرنا سابقًا. بهذا الطريقة يمكننا الوصول إلى دالة index التي أنشأناها قبل قليل في ملف views.py الموجود في مجلد polls (أو حزمة polls لنكون أكثر دقة) وذلك تمهيدًا لربطها بالمسار الذي نرغب فيه. أضفنا كذلك الشيفرة التالية إلى قائمة urlpatterns: url(r'/polls', views.index), وهي عبارة عن دالة وظيفتها ربط المسار الذي نحدده في المعامل الأول بالعرض الذي نحدده في المعامل الثاني. لاحظ أن المسار عبارة عن سلسلة نصية مسبوقة بحرف r صغير وذلك لإخبار بايثون بأن يتعامل مع هذه السلسلة النصية على أنّها سلسلة خام raw، بمعنى أنه سيتم تجاوز جميع العلامات الخاصة المستخدمة في هذه السلسلة، وهذا ضروري جدًّا، لأن Django يستخدم التعبيرات النظامية Regular Expressions في تحديد المسارات وتمرير المتغيرات، وهذه التعبيرات تستخدم الكثير من الرموز التي يجب تجاوزها لتعمل الشيفرة بالشكل الصحيح. سنتعرف على المسارات وآلية عملها وكيفية استخدام التعبيرات النظامية، في الدروس اللاحقة. يمكنك الآن التوجه إلى مجلد المشروع وتشغيل الخادوم الخاص بـ Django عن طريق سطر الأوامر من خلال الأمر التالي: python manage.py runserver انتقل في المتصفح إلى العنوان التالي: http://127.0.0.1:8000/polls لتشاهد عبارة الترحيب في واجهة الموقع. يمكننا استخدام شيفرة HTML ضمن السلسلة النصية التي ترجعها دالة العرض، وللقيام بذلك افتح ملف polls/view.py وعدّله ليصبح بالشكل التالي: from django.http import HttpResponse def index(request): html = """ <html dir="rtl"> <head> <title>تطبيق الاقتراعات</title> </head> <body> <h1>تطبيق الاقتراعات</h1> <p>مرحبًا بك في تطبيق الاقتراعات، هذه هي الصفحة الرئيسية.</p> </body> </html> """ return HttpResponse(html) من المؤكد أن التطبيقات التي نراها على صفحات الإنترنت لا تتمتع بهذه البساطة الشديدة، وهذا يعني أن استخدام شيفرة HTML ضمن دالة العرض أمر غير عملي على الإطلاق، وهنا تظهر الحاجة إلى فصل هذه الشيفرات عن العروض وهذه هي وظيفة القوالب Templates والتي سنتعرف إليها في الدروس اللاحقة. خاتمة تعرفنا في هذا الدرس على مفهومي المشروع والتطبيق في Django، وقمنا بكتابة العرض الأول وتعرفنا بشكل مختصر على المسارات Urls. سنتعرف في الدرس القادم على كيفية التعامل مع قواعد البيانات من خلال النماذج Models، وكذلك سنتعرف على كيفية تهجير قواعد البيانات، وكذلك الاستعلام عن البيانات برمجيًا، وذلك لتهيئة قاعدة البيانات التي سنستخدمها في تطبيق الاقتراعات.1 نقطة
-
كانت البرامج التي اطلعنا عليها لحد الآن تعرض رسائل على الشاشة فقط، الذي لا يشتمل على حسابات حقيقية كثيرة. سيبين لك هذا الفصل طريقة قراءة الدخل من لوحة المفاتيح، واستخدام ذلك الدخل لحساب نتائج معينة، ثم تنسيق تلك النتائج وعرضها على الخرج. صنف System لقد استخدمنا System.out.println كثيرًا، لكن ربما لم تنتبه لمعناها. System هو صنف يوفر توابع متعلقة "بالنظام" (system) أو البيئة التي تعمل فيها البرامج. كما أنه يوفر أيضًا System.out، وهي قيمة خاصة توفر توابع لعرض الخرج، ومنها تابع println. في الواقع، يمكنك استخدام System.out.println لعرض قيمة System.out: System.out.println(System.out); النتيجة هي: java.io.PrintStream@685d72cd يدل هذا الخرج على أن System.out هو PrintStream، معرف ضمن حزمة تدعى java.io. الحزمة (package) هي مجموعة من الأصناف المتعلقة ببعضها؛ تحوي حزمة java.io الأصناف المتعلقة بالدخل والخرج اللذان يرمز لهما بالحرفين I/O والتي تعني Input and Output. أما الأرقام والأحرف بعد علامة @ فهي تمثل عنوان (address) الكائن System.out بشكل رقم ست عشري (في الأساس 16). عنوان القيمة هو موقعها في ذاكرة الحاسوب، وهذا الموقع قد يختلف بين الحواسيب المختلفة (أو عند تشغيل البرنامج في المرات التالية). كان العنوان في هذا المثال 685d72cd، لكن إذا شغلت البرنامج نفسه ثانية فقد تحصل على عنوان مختلف. كما يبين الشكل التالي، الصنف System معرفٌ في ملف اسمه System.java، وهناك ملف آخر يعرف فيه الصنف PrintStream اسمه PrintStream.java. هذه الملفات تابعة لمكتبة (library) لغة Java، وهي عبارة عن مجموعة ضخمة من الأصناف التي تستطيع استخدامها في برامجك. تشير تعليمة System.out.println إلى المتغير out ضمن الصنف System، وهو كائن من النوع PrintStream يوفر تابعًا يدعى println. صنف Scanner يحوي الصنف System أيضًا القيمة الخاصة System.in، وهي InputStream يوفر توابع لقراءة الدخل من لوحة المفاتيح. استخدام هذه التوابع ليس سهلًا؛ لكن لحسن الحظ أن Java توفر أصنافًا أخرى تسهل مهام الإدخال الشائعة. مثلًا، يوفر الصنف Scanner توابع لإدخال الكلمات، والأرقام، وغيرها من البيانات. يتوفر Scanner في الحزمة java.util، التي تحوي أصنافًا مفيدة جدًا تدعى "utility classes" (أصناف المرافق). قبل أن تتمكن من استخدام Scanner، عليك استيراده كالتالي: import java.util.Scanner; توضح تعليمة الاستيراد (import statement) للمترجم أنك عندما تقول Scanner فأنت تقصد أحد الأصناف المعرفة في java.util. هذه التعليمة ضرورية لأنه يحتمل وجود أصناف أخرى اسمها Scanner في حزم أخرى. استخدام تعليمة الاستيراد يجعل الكود واضحًا. لا يمكن استخدام تعليمات الاستيراد داخل تعريف صنف. تقليديًا، توضع تعليمات الاستيراد في بداية الملف. بعد ذلك عليك إنشاء Scanner: Scanner in = new Scanner(System.in); يصرح هذا السطر عن متغير من نوع Scanner ويسميه in وينشئ كائنًا جديدًا من نوع Scanner الذي يستقبل المدخلات من System.in. يوفر Scanner تابعًا يدعى nextLine الذي يقرأ الدخل من لوحة المفاتيح وترجع String. في المثال التالي نقرأ سطرين ونعيد إخراجهما للمستخدم: import java.util.Scanner; public class Echo { public static void main(String[] args) { String line; Scanner in = new Scanner(System.in); System.out.print("Type something: "); line = in.nextLine(); System.out.println("You said: " + line); System.out.print("Type something else: "); line = in.nextLine(); System.out.println("You also said: " + line); } } إذا أغفلت تعليمة الاستيراد ثم استخدمت Scanner سوف يعطي المترجم خطأ يشبه "Cannot find symbol" (لا يمكن العثور على الرمز). هذا يعني أن المترجم لا يعرف ماذا تعني عندما تقول Scanner. لعلك تتساءل لم يمكننا استخدام الصنف System دون استيراده؟ السبب هو أن الصنف System ينتمي لحزمة java.lang، التي تستورد آليًا في جميع البرامج. حسب وثائق اللغة فإن java.lang "توفر أصنافًا جوهرية في تصميم لغة البرمجة Java". صنف String ينتمي أيضًا لحزمة java.lang. بنية البرنامج لقد تعرفنا الآن على كافة العناصر التي تتكون منها برامج Java. يوضح الشكل التالي هذه العناصر التنظيمية. عناصر لغة Java، من الأكبر إلى الأصغر كمراجعة سريعة، الحزمة هي مجموعة أصناف، والأصناف تعرف فيها توابع. التوابع تحوي تعليمات، والتعليمات قد تحوي تعابير. تتكون التعابير من علامات (tokens)، وهي العناصر الأساسية للبرنامج، وتشمل الأرقام، وأسماء المتغيرات، والعوامل الحسابية، والكلمات المفتاحية، والرموز مثل الأقواس والفواصل المنقوطة. تأتي النسخة القياسية من Java مزودة بعدة آلاف من الأصناف التي يمكنك استيرادها، وهذا مثير جدًا ومخيف في نفس الوقت. يمكنك تصفح مكتبة جافا حيث أنها نفسها مكتوبة بلغة Java. لاحظ أن هناك فرق كبير بين لغة Java، التي تُعرّف التراكيب النحوية ومعاني العناصر المبينة في الشكل السابق، وبين مكتبة Java، التي توفر الأصناف المرفقة مع اللغة. التحويل من إنش إلى سنتيمتر دعنا نلق نظرة على مثال مفيد قليلًا. رغم أن معظم دول العالم اعتمدت النظام المتري للأوزان والمقاييس، إلا أن بعض الدول لا تزال عالقة مع الواحدات الإنكليزية. مثلًا، عندما يتحدث الأمريكان مع أصدقائهم من أوربا عن الطقس، قد يحتاجون للتحويل بين الدرجات المئوية والفهرنهايت. أو قد يرغبون بتحويل الأطوال من واحدة الإنش إلى السنتيمتر. يمكننا كتابة برنامج يساعد في ذلك. سنستخدم Scanner لإدخال القياسات بالإنش، ثم نحولها إلى سنتيمتر، ثم نعرض النتائج. تصرح السطور التالية عن المتغيرات وتنشئ Scanner: int inch; double cm; Scanner in = new Scanner(System.in); الخطوة التالية هي طلب المدخلات من المستخدم. سنستخدم تعليمة print بدلًا من println حتى يتمكن من كتابة المدخلات على نفس السطر. وسنستخدم تابع nextInt من الصنف Scanner، التي تقرأ الدخل من لوحة المفاتيح وتحوله إلى عدد صحيح: System.out.print("How many inches? "); inch = in.nextInt(); بعد ذلك، سوف نضرب الرقم المدخل بالقيمة 2.54، بما أننا نعرف أن كل إنش هو 2.54 سنتيمتر، ثم نعرض النتيجة: cm = inch * 2.54; System.out.print(inch + " in = "); System.out.println(cm + " cm"); هذه الأكواد تعمل بشكل صحيح، لكن هناك مشكلة صغيرة. إذا قرأ مبرمج آخر هذا الكود، فقد يتساءل من أين أتت القيمة 2.54. من أجل مصلحة الآخرين (ومصلحتك المستقبلية) يفضل إسناد هذه القيمة إلى متغير له اسم واضح. سنوضح ذلك في القسم التالي. القيم الحرفية والثوابت تدعى القيم التي تكتب في البرنامج، مثل 2.54، بالقيم الحرفية (literals). بشكل عام، ليس هناك مشكلة باستخدام القيم الحرفية. لكن عندما تظهر أرقام مثل 2.54 في التعابير دون أي تفسير، سوف تجعل الكود أصعب على القراءة. وإذا ظهرت القيمة نفسها مرات عديدة، وكانت هناك احتمال أن تتغير هذه القيمة في المستقبل، فهذا يجعل الكود أصعب على الصيانة والتجديد. هذه القيم تدعى أحيانًا الأرقام السحرية (magic numbers) (مع العلم أن الأشياء "السحرية" ليست جيدة هنا). من الممارسات الجيدة إسناد هذه القيم السحرية إلى متغيرات لها أسماء معبرة، كما يلي: double cmPerInch = 2.54; cm = inch * cmPerInch; هذه النسخة أسهل للقراءة وأقل عرضة للخطأ، لكن لا يزال هناك مشكلة. المتغيرات تتغير، لكن عدد السنتيمترات في الإنش الواحد لا يتغير. يجب ألا تتغير قيمة cmPerInch بعد إسناد قيمته أول مرة. توفر Java الكلمة المفتاحية final لفرض هذا الشرط. final double CM_PER_INCH = 2.54; التصريح عن متغير بكلمة final يعني أنه لا يمكن إسناد قيم جديدة له بعد نهيئته أول مرة. إذا حاولت تغيير قيمته، سوف يعطيك المترجم خطأ. تدعى المتغيرات التي يصرح عنها بكلمة final بالثوابت (constants). حسب التقاليد، تكتب أسماء الثوابت بحروف كبيرة، وتستخدم الشرطة المنخفضة (_) للفصل بين الكلمات. ترجمة -وبتصرف- للفصل Input and output من كتاب Think Java: How to Think Like a Computer Scientist لكاتبيه Allen B. Downey و Chris Mayfield.1 نقطة