أعجوبة

البرمجيات الحُرة والمفتوحة المصدر

أدوات المستخدم

أدوات الموقع


docs:django-basics

اختلافات

عرض الاختلافات بين النسخة المختارة و النسخة الحالية من الصفحة.

رابط إلى هذه المقارنة

جانبي المراجعة السابقةالمراجعة السابقة
المراجعة التالية
المراجعة السابقة
docs:django-basics [2015/09/20 14:47] alsadidocs:django-basics [2015/09/20 14:57] (حالي) alsadi
سطر 1: سطر 1:
 +{{tag>مقالات برمجة بايثون بدهيات جانغو أطر ويب}}
 +====== بدهيات إطار الويب جانغو Django ======
 +
 +===== الحصول على جانغو =====
 +==== طرق الحصول على جانغو ====
 +يفضل أن تعود لمقالة [[python_basics#استخدام_مستودعات_التوزيعة|بدهيات بايثون]] حيث هناك فصل للحصول على الحزم وحزمة جانغو ليست استثناء.
 +
 +يمكن تثبيت جانغو من خلال مدير حزم بايثون pip والذي أصبح منذ 2.7.9 و 3.4.0 جزء من توزيعة بايثون القياسية (في لينكس عليك تثبيت الحزمة ''python-pip'' من مدير الحزم في توزيعتك).  وينصح أن يتم ذلك من خلال مجلد البيئة الافتراضية من خلال أداة virtualenv وهي الأخرى يمكن الحصول عليها من مدير حزم بايثون pip.
 +
 +هذه جلسة بصلاحيات المستخدم الجذر (وضعت فيها أشياء زائدة قصدا الشيء الوحيد الضروري من السطر الأول هو python-pip)
 +
 +<code bash>
 +yum install python-pip python-pillow python-lxml python-psutil python-simplejson python-crypto  PyYAML MySQL-python python-psycopg2 libxslt-python python-greenlet python-gevent  
 +pip install virtualenv
 +</code>
 +
 +إذا كنت تستخدم أوبنتو apt-get install python-pip عوضا عن السطر الأول.
 +
 +الآن وبصلاحيات المستخدم العادي اعمل  مجلد البيئة الافتراضية المعزولة
 +
 +<code bash>
 +virtualenv --system-site-packages myenv
 +cd myenv
 +source bin/activate
 +pip install Django
 +</code>
 +
 +وكلما أردت العمل على مشروعك تذهب إلى ذلك المجلد الذي سميناه myenv وهو الذي فيه bin ثم تكتب ''source bin/activate''
 +
 +=== ويندوز ===
 +نظام ويندوز لا يحتوي على لغة بايثون لذا عليك الحصول عليها بنفسك. موقع بايثون يوفر ملف تثبيت msi للغة يقوم بتثبيت بايثون. تأكد من أن مسارات بايثون و pip و virtualenv مثبتة في مسار النظام PATH
 +
 +==== التأكد من سلامة تثبيته ====
 +افتح سطر الأوامر وشغل بايثون واكتب فيه import django إذا كان جانغو مثبت بشكل صحيح لن تحصل على ImportError بل ستكون الشاشة هكذا:
 +<code>
 +Python 2.7 (r27:82500, Sep 16 2010, 18:02:00) 
 +[GCC 4.5.1 20100907 (Red Hat 4.5.1-3)] on linux2
 +Type "help", "copyright", "credits" or "license" for more information.
 +>>> import django
 +>>> 
 +</code>
 +
 +===== إنشاء تطبيق =====
 +
 +قم بتنفيذ أداة إدارة جانغو django-admin أو django-admin.py مع تمرير كلمة startproject متبوعة باسم المشروع myproj على سبيل المثال
 +<code bash>
 +django-admin startproject myproj
 +cd myproj
 +</code>
 +
 +وهناك أنشئ تطبيق الويب بالأداة manage.py الموجودة داخل المجلد الجديد وذلك بكتابة python متبوعة ب manage.py متبوعة ب startapp ثم اسم التطبيق
 +
 +<code bash>
 +python ./manage.py startapp myapp
 +</code>
 +
 +تحذير: لا تستخدم django-admin إلا لإنشاء المشروع أما بقية الأوامر فتكون من خلال manage.py الموجودة داخل المشروع.
 +
 +وبهذا نكون عملنا هيكل الملفات لتطبيق الويب والذي يبدو كما في هذه الصورة
 +
 +{{ :docs:dj-tree1.png |شجرة الملفات لمشروعنا على جانغو}}
 +
 +هذا التطبيق الذي عملنا يعمل الآن. لتشغيله اكتب 
 +<code bash>
 +python ./manage.py runserver
 +</code>
 +
 +وستشاهد ما يشبه
 +
 +{{ :docs:dj-it-worked.png?480 |إنه يعمل}}
 +
 +تقول لك هذه الصورة أن عليك اختيار قاعدة البيانات
 +
 +===== اختيار قاعدة البيانات =====
 +افتح ملف الإعدادات settings.py وابحث عن سطر في رأس الملف يحدد قاعدة البيانات ستجد جزء يشبه
 +<code python>
 +DATABASES = {
 +    'default': {
 +        'ENGINE': 'django.db.backends.', # Add 'postgresql_psycopg2', 'postgresql', 'mysql', 'sqlite3' or 'oracle'.
 +        'NAME': '',                      # Or path to database file if using sqlite3.
 +        'USER': '',                      # Not used with sqlite3.
 +        'PASSWORD': '',                  # Not used with sqlite3.
 +        'HOST': '',                      # Set to empty string for localhost. Not used with sqlite3.
 +        'PORT': '',                      # Set to empty string for default. Not used with sqlite3.
 +    }
 +}
 +
 +</code>
 +
 +يمكنك الآن اختيار أي قاعدة بيانات سواء PostgreSQL أو MySQL أو Oracle لكن لأغراض تجربة جانغو سنستخدم sqlite3 وهي قاعدة بيانات تكون عبارة عن ملف (لن نحتاج لخادم) ودعمها موجود ضمنا في بايثون أي:
 +<code python>
 +DATABASES = {
 +    'default': {
 +        'ENGINE': 'django.db.backends.sqlite3', 
 +        'NAME': 'myproj.db',
 +</code>
 +
 +ثم احفظ الملف.
 +
 +===== واجهة الإدارة =====
 +==== تفعيل واجهة الإدارة ====
 +تحتوي جانغو على واجهة جميلة تستخدم لإدارة التطبيق بل وتعديل المدخلات. لتفعيلها افتح ملف الإعدادات settings.py وأزل علامة التعليق # عن أول سطري الإدارة ووثائق الإدارة لتصبح كما يلي
 +
 +<code python>
 +INSTALLED_APPS = (
 +    'django.contrib.auth',
 +    'django.contrib.contenttypes',
 +    'django.contrib.sessions',
 +    'django.contrib.sites',
 +    'django.contrib.messages',
 +    # Uncomment the next line to enable the admin:
 +    'django.contrib.admin',
 +    # Uncomment the next line to enable admin documentation:
 +    'django.contrib.admindocs',
 +)
 +</code>
 +
 +ثم فعّل الروابط في ملف urls.py بطريقة مشابهة في رأس الملف
 +<code python>
 +# Uncomment the next two lines to enable the admin:
 +from django.contrib import admin
 +admin.autodiscover()
 +</code>
 +وفي ذيل نفس الملف
 +
 +<code python>
 +urlpatterns = patterns('',
 +    # Example:
 +    # (r'^myproj/', include('myproj.foo.urls')),
 +
 +    # Uncomment the admin/doc line below to enable admin documentation:
 +    (r'^admin/doc/', include('django.contrib.admindocs.urls')),
 +
 +    # Uncomment the next line to enable the admin:
 +    (r'^admin/', include(admin.site.urls)),
 +)
 +</code>
 +
 +احفظ الملفين ثم نفذ أداة الإدارة متبوعة ب syncdb هكذا
 +<code>
 +python manage.py syncdb
 +</code>
 +
 +<note important>يجب تنفيذ syncdb بعد عمل أي تعديل على نموذج قاعدة البيانات</note>
 +
 +تفعيل واجهة الإدارة يعني ضمنا تفعيل نظام المواثقة بما فيه جداول المستخدمين لذا فإن الأمر السابق سيطلب عمل مستخدم خارق (المدير) وتحديد كلمته السرية
 +
 +<code>
 +You just installed Django's auth system, which means you don't have any superusers defined.
 +Would you like to create one now? (yes/no): yes
 +Username (Leave blank to use 'alsadi'): 
 +E-mail address: alsadi@somewhere.com
 +Password: 
 +Password (again): 
 +...
 +No fixtures found.
 +</code>
 +
 +الآن أعد تشغيل الخادم بالأمر
 +
 +<code bash>
 +python ./manage.py runserver
 +</code>
 +
 +ثم ادخل عبر المتصفح للعنوان http://127.0.0.1:8000/admin
 +
 +{{ :docs:dj-admin.png?480 |واجهة الإدارة}}
 +==== مزايا واجهة الإدارة ====
 +
 +==== لغة المشروع ====
 +هناك سطر في ملف الإعدادات يحدد اللغة يمكنك أن تجعله يشير للغة العربية هكذا
 +<code python>
 +# Language code for this installation. All choices can be found here:
 +# http://www.i18nguy.com/unicode/language-identifiers.html
 +LANGUAGE_CODE = 'ar'
 +</code>
 +
 +{{ :docs:dj-admin-ar1.png?480 |شاشة الولوج بالعربية}}
 +
 +===== عمل نموذج البيانات =====
 +==== تفعيل التطبيق ====
 +قبل عمل أي شيء يجب إضافة تطبيقنا إلى INSTALLED_APPS في ملف settings.py 
 +<code python>
 +INSTALLED_APPS = (
 +    'django.contrib.auth',
 +    'django.contrib.contenttypes',
 +    'django.contrib.sessions',
 +    'django.contrib.sites',
 +    'django.contrib.messages',
 +    # Uncomment the next line to enable the admin:
 +    'django.contrib.admin',
 +    # Uncomment the next line to enable admin documentation:
 +    'django.contrib.admindocs',
 +    'myapp',
 +)
 +</code>
 +==== تصميم نموذج البيانات ====
 +يجب أن نحدد نموذج البيانات الخاص بمشروعنا وذلك بالدخول في مجلد myapp ثم فتح الملف models.py
 +مثلا 
 +<code python>
 +from django.db import models
 +from django.contrib.auth.models import User
 +
 +# Create your models here.
 +class Tag(models.Model):
 +  name = models.CharField(max_length=200)
 +  def __unicode__(self):
 +    return self.name
 +
 +class Article(models.Model):
 +  title = models.CharField(max_length=200)
 +  body = models.TextField()
 +  user = models.ForeignKey(User)
 +  tags = models.ManyToManyField(Tag)
 +  def __unicode__(self):
 +    return self.title
 +
 +</code>
 +
 +==== تسجيل النموذج في واجهة الإدارة ====
 +
 +وفي نفس المجلد نعمل ملف admin.py يضيف نموذجنا إلى واجهة الإدارة
 +<code python>
 +from django.contrib import admin
 +from myapp.models import *
 +
 +admin.site.register(Tag)
 +admin.site.register(Article)
 +</code>
 +
 +الآن اعمل syncdb ثم ادخل لواجهة الإدارة لتجد كل ما ترغب به
 +
 +==== تخصيص طريقة العرض ====
 +
 +دالة __unicode__ في كل صنف تحدد طريقة عرض المدخلة الواحدة مثلا يمكننا أن نظهر اسم المستخدم إلى جانب عنوان المقالة هكذا
 +
 +<code python>
 +  def __unicode__(self):
 +    return self.user.username+u" : "+self.title
 +</code>
 +
 + {{ :docs:dj-admin-list-articles-user.png?480 |عرض اسم المستخدم إلى جانب عنوان المقالة}}
 +
 +بل ويمكننا عرض التصنيفات
 +<code python>
 +  def __unicode__(self):
 +    return self.user.username+u" : "+self.title+u" @ "+(", ".join(map(lambda i: i.name ,self.tags.all())))
 +</code>
 +بل وبطريقة تويترية
 +<code python>
 +  def __unicode__(self):
 +    return u"@"+self.user.username+u" : "+self.title+u" #"+(" #".join(map(lambda i: i.name ,self.tags.all())))
 +</code>
 +
 +{{ :docs:dj-admin-list-articles-twt.png?480 |العرض بطريقة تويترية}}
 +==== تعديل النموذج ====
 +في أي لحظة يمكنك تعديل النموذج وإضافة جداول جديدة لكن إضافة حقول في الجدول الواحد لا يمكن القيام به بسهولة.
 +لهذا فلنقم بحذف ملف قاعدة البيانات ولنعدل ملف النموذج ونضيف حقل مفهرس يبين هل المقالة منشورة وحقل يحتوي تاريخ النشر وليكن مفهرسا ولنجعل العنوان فريدا
 +
 +<code python>
 +from datetime import datetime
 +
 +class Article(models.Model):
 +  title = models.CharField(max_length=200, unique=True)
 +  body = models.TextField()
 +  published = models.BooleanField(verbose_name=u"Published?", default=True, help_text=u"If not enabled it won't appear for browsing")
 +  ctime = models.DateTimeField(verbose_name=u"Creation time", db_index=True, default=datetime.now)
 +  user = models.ForeignKey(User)
 +  tags = models.ManyToManyField(Tag)
 +  def __unicode__(self):
 +    return u"@"+self.user.username+u" : "+self.title+u" #"+(" #".join(map(lambda i: i.name ,self.tags.all())))
 +</code>
 + 
 +أهم أنواع البيانات هي
 +  * AutoField
 +  * BigIntegerField
 +  * BooleanField
 +  * CharField
 +  * CommaSeparatedIntegerField
 +  * DateField
 +  * DateTimeField
 +  * DecimalField
 +  * EmailField
 +  * FileField
 +  * FilePathField
 +  * FloatField
 +  * ImageField
 +  * IntegerField
 +  * IPAddressField
 +  * NullBooleanField
 +  * PositiveIntegerField
 +  * PositiveSmallIntegerField
 +  * SlugField
 +  * SmallIntegerField
 +  * TextField
 +  * TimeField
 +  * URLField
 +  * XMLField
 +
 +==== العلاقات ====
 +
 +لاحظ طريقة عمل العلاقات
 +  * حقل ForeignKey ويعني علاقة Many to One (في مثالنا تربط العلاقة عدة مقالات للمستخدم الواحد ولا يجوز أن يكون هناك مقالة تعود لأكثر من مستخدم)
 +  * حقل ManyToManyField ويعني كما يشير اسمه ارتباط عدة تصنيفات بعدة مقالات
 +  * علاقة OneToOneField ويعني واحد لواحد
 +
 +المعامل الأول لها هو النموذج الآخر الذي ترتبط معه أو اسمه (على شكل نص) إن لم يكن معرفا بعد.
 +
 +<note>يجوز أن تعمل العلاقة بين الجدول ونفسه مثلا المستخدم قد يكون له حقل أصدقاء والذين هم أيضا مستخدمون!</note>
 +
 +يفضل أن تحدد نوع العلاقة related_name عند وجود غموض مثلا لو كان للمقالة مستخدمان أحدهما صاحب المقالة والثاني صاحب آخر تعديل فإنها تكون هكذا
 +<code python>
 +  author = models.ForeignKey(User, related_name="created_by")
 +  last_editor = models.ForeignKey(User, related_name="last_edit_by")
 +</code>
 +
 +==== تخصيص طريقة الإدارة ====
 +يمكنك تخصيص صفحات الإدارة عبر عمل صنف مشتق من الصنف admin.ModelAdmin وتمريره كمعامل ثاني للدالة admin.site.register في ملف admin.py مثلا
 +
 +<code python>
 +from django.contrib import admin
 +from myapp.models import *
 +
 +class ArticleAdmin(admin.ModelAdmin):
 +  list_display = ('title', 'user', 'ctime')
 +  list_filter = ['ctime', 'published', 'tags']
 +  date_hierarchy = 'ctime'
 +  search_fields = ['title']
 +  list_per_page = 10
 +  fieldsets = [
 +        (None, {'fields': ['title', 'body']}),
 +        (u'Extra Information', {'fields': ['user', 'tags']}),
 +        (u'Advanced', {'classes': ['collapse'], 'fields': ['published', 'ctime']}),
 +    ]
 +
 +admin.site.register(Article, ArticleAdmin)
 +</code>
 +
 +الآن جرب الدخول لصفحة الإدارة وسترى أن عرض قائمة المقالات أصبحت عبارة عن جدول بعدة أعمدة (يمكن النقر على رأس العمود للترتيب) هي العنوان والمستخدم والوقت وليس مجرد عرض للتمثيل النصي الذي تعيده الدالة __unicode__. كذلك أصبحت تحتوي على بحث (في حقل العنوان) وفلترة حسب التاريخ وحالة النشر والتصنيفات في صندوق جانبي وتحت صندوق البحث هناك صندوق للتصفح عبر التاريخ وهناك تقسيم للصفحات.
 +
 +لا نستطيع إضافة عمود يبين ألتصنيفات tags لأنها حقل many to many أي هناك أكثر من تصنيف. لكن يمكن التحايل على ذلك بعمل حقل وهمي يولد تلقائيا (غير موجود في قاعدة البيانات) مثلا وليكن اسمه tags_as_text وذلك بإضافة الدالة التالية داخل الصنف Article في النموذج models.py
 +
 +<code python>
 +  tags = models.ManyToManyField(Tag)
 +  def tags_as_text(self):
 +    return u" #"+(" #".join(map(lambda i: i.name ,self.tags.all())))
 +  tags_as_text.short_description = u'Tags List'
 +</code>
 +
 +ثم نعدل أعمدة اللائحة لتكون
 +<code python>
 +  list_display = ('title', 'user', 'tags_as_text', 'ctime')
 +</code>
 +
 +{{ :docs:dj-admin-list-custom.png?480 |عرض أجمل في صفحة الإدارة}}
 +
 +يمكننا جعل عرض لائحة التصنيفات تحتوي على عدد المقالات فيه. لنحرر نموذج التصنيفات في models.py ليكون
 +
 +<code python>
 +class Tag(models.Model):
 +  name = models.CharField(max_length=200)
 +  def articles_count(self):
 +    return self.article_set.count()
 +  articles_count.short_description = u'Number of Articles'
 +  def __unicode__(self):
 +    return self.name
 +</code>
 +وفي الإدارة admin.py
 +<code python>
 +class TagAdmin(admin.ModelAdmin):
 +  list_display = ('name', 'articles_count')
 +
 +admin.site.register(Tag, TagAdmin)
 +</code>
 +
 +{{ :docs:dj-admin-tags-list-with-count.png?480 |التصنيفات مع عددها}}
 +
 +ليس هذا فحسب بل إن شاشة تحرير المقالة في الإدارة أصبحت الآن أجمل حيث أن عدد من الحقول أصبحت مجمعة مثلا المستخدم user و التصنيفات tags أصبحت داخل صندوق Extra Information والتاريخ وهل هي منشورة أصبحت في صندوق منكمش اسمه Advanced وبالنقر عليه يتوسع ويظهر كل هذا fieldsets.
 +
 +{{ :docs:dj-admin-articles-new.png?480 |الواجهة المعدلة لتحرير مقالة في الإدارة}}
 +
 +في وثائق جانغو هناك مثال لبرنامج استطلاع رأي يحتوي النموذج فيه على السؤال ويرتبط بعدد من الاختيارات (الإجابات) لكل منها مجموع الأصوات عليها ويراد أن تحتوي شاشة تحرير السؤال على إضافة تلقائية لثلاث إجابات مرتبطة بذلك السؤال وذلك عبر
 +<code python>
 +  inlines = [ChoiceInline]
 +</code>
 +حيث ChoiceInline معرفة في admin.py هكذا
 +<code python>
 +class ChoiceInline(admin.StackedInline):
 +    model = Choice
 +    extra = 3
 +</code>
 +
 +==== الصلاحيات ====
 +يمكنك عمل مستخدمين جدد وتحدد أنهم جزء من الطاقم stuff أي يمكنهم الدخول إلى صفحة الإدارة.
 +لست مضطرا لإعطائهم كل الصلاحيات مثلا يمكنك السماح لهم فقط بإضافة مقالات وتعديل المقالات.
 +
 +<code python>
 +  readonly_fields=['ctime', 'published']
 +</code>
 +==== اختيار المستخدم تلقائيا ====
 +المفروض أن يتم اختيار المستخدم أضاف المقالة بل يتم ذلك تلقائيا لعمل ذلك نحذف 'user' من قائمة fieldsets ثم نضيف الدالة save_model داخل الصنف ArticleAdmin في ملف admin.py
 +<code python>
 +  def save_model(self, request, obj, form, change):
 +    obj.user = request.user
 +    obj.save()
 +</code>
 +
 +===== شرح هيكلية المشروع =====
 +
 +==== مفهوم MVC في جانغو ====
 +مفهوم MVC والذي عني تقسم المشروع إلى نموذج بيانات Model و طريقة عرض View وحاكم Controller مثلا لا يجوز أن يحتوي الحاكم على كود html أو أي عناصر تصميم بل على الكود الذي يحضر العناصر من النموذج ويمررها إلى نظام العرض كذلك لا يجوز أن يحتوي العرض على كود بل على تصميم فقط.
 +
 +==== اختلاف المصطلحات ====
 +
 +في جانغو الأمر نفسه لكن اختلفت الأسماء فهم يسمون الحاكم باسم العرض View ويسمون العرض باسم القالب Template
 +
 +==== هيكيلية الملفات ====
 +  * الملف manage.py أداة الإدارة
 +  * الملف settings.py ملف الإعدادات مثل اللغة والمنطقة الزمنية والتطبيقات والبينيات Middleware
 +  * الملف urls.py يحتوي على ربط نمط قياسي regex من عناوين url وما يقابلها من دوال الحاكم أو العرض في مصطلح جانغو
 +  * مجلدات التطبيق وفي مثالنا myapp.py
 +    * ملف admin.py لتخصيص واجهة الإدارة
 +    * ملف models.py الذي يعرف نموذج البيانات
 +    * ملف views.py وهو الذي يحتوي على دوال الحاكم (أو العرض بمصطلح جانغو)
 +
 +==== تعريف القوالب ====
 +اعمل مجلد باسم templates في مجلد المشروع (وليس التطبيق) أي إلى جوار ملف settings.py ثم حرر هذا الأخير وحرره كي تحدد مسار القوالب فيه
 +<code python>
 +import os.path
 +# ...
 +TEMPLATE_DIRS = (
 +    os.path.join(os.path.dirname(__file__), 'templates'),
 +)
 +</code>
 +ونحن بهذا نخبر جانغو أن مسار القوالب هي في templates الموجودة في مجلد الذي يحتوي الملف الحالي أي settings.py
 +
 +==== عمل صفحة رئيسية ====
 +افتح ملف views.py في مجلد myapp وضع فيه
 +<code python>
 +from django.shortcuts import render_to_response
 +from models import *
 +def homepage(request):
 +  return render_to_response('homepage.html', {'articles_list':Article.objects.all()} )
 +</code>
 +
 +افتح ملف urls.py وحرر المسارات فيه كي تبدو هكذا
 +<code python>
 +from myapp.views import *
 +urlpatterns = patterns('',
 +    (r'^$', homepage),
 +
 +    # Uncomment the admin/doc line below to enable admin documentation:
 +    (r'^admin/doc/', include('django.contrib.admindocs.urls')),
 +
 +    # Uncomment the next line to enable the admin:
 +    (r'^admin/', include(admin.site.urls)),
 +)
 +</code>
 +حيث ربطنا العنوان الخالي مع دالة homepage التي تجلب كل المقالات ثم تركبها على قالب homepage.html وضع في ذلك القالب ما يشبه
 +<code html>
 +<html>
 +<head>
 +<title>MyApp using Django</title>
 +</head>
 +<body>
 +<h1>MyApp using Django</h1>
 +<ul>
 +{% for a in articles_list %}
 +<li>{{ a.title }}</li>
 +{% endfor %}
 +</ul>
 +</body>
 +</html>
 +</code>
 +
 +الآن زر الصفحة الرئيسية وسترى ما يشبه
 +
 +{{ :docs:dj-trivial-homepage.png?480 |الصفحة الرئيسية}}
 +===== العروض العامة Generic Views =====
 +حتى لا تضيع وقتك في عمل الصفحات القياسية التي تعرض قائمة بالكائنات التي عرفتها في النموذج أو لتحريرها أو إضافتها توفر جانغو عددا من العروض العامة من أهمها
 +
 +  * django.views.generic.list_detail.object_list
 +  * django.views.generic.list_detail.object_detail
 +  * django.views.generic.create_update.create_object
 +  * django.views.generic.create_update.update_object
 +
 +==== عرض object_list ====
 +
 +مثلا نستعمل object_list هكذا
 +
 +<code python>
 +from myapp.views import *
 +urlpatterns = patterns('',
 +    (r'^$', homepage),
 +    (r'^articles/$', 'django.views.generic.list_detail.object_list', {
 +      'queryset': Article.objects.all(),
 +      'paginate_by': 10,
 +      'template_name': 'articles.html',
 +      'template_object_name':'articles',
 +    }),
 +
 +    # Uncomment the admin/doc line below to enable admin documentation:
 +    (r'^admin/doc/', include('django.contrib.admindocs.urls')),
 +
 +    # Uncomment the next line to enable the admin:
 +    (r'^admin/', include(admin.site.urls)),
 +)
 +</code>
 +
 +لاحظ أننا مررنا عدد من المعاملات لدالة العرض العامة  django.views.generic.list_detail.object_list وهي
 +  * المعامل queryset طريقة احضار الكائنات
 +  * المعامل paginate_by عدد الكائنات بالصفحة
 +  * المعامل template_object_name وقيمته تلحق بعبارة _list قبل أن تمرر للقالب والقيمة التلقائية هي objects
 +  * المعامل template_name هي اسم القالب
 +
 +يمكنك نسخ القالب السابق homepage.html باسم جديد هو articles.html وانظر النتيجة
 +لاحظ أنه عرض أول 10 عناصر فقط وعند زيارة الصفحة
 +  * http://localhost:8000/articles/?page=2
 +
 +{{ :docs:dj-list-pg2.png?480 |الصفحة الثانية}}
 +
 +تم عرض بقية العناصر. لكن كيف للمستخدم أن يعرف أن هناك صفحة ثانية؟ نحتاج لإضافة ما يلي إلى نهاية القالب قبل انتهاء وسم إغلاق body هكذا 
 +<code html>
 +<hr/>
 +        <span class="current">
 +            Page {{ page_obj.number }} of {{ paginator.num_pages }}.
 +        </span>
 +<hr/>
 +<div class="pagination">
 +    <span class="step-links">
 +        {% if page_obj.has_previous %}
 +            <a href="?page={{ page_obj.previous_page_number }}">previous</a>
 +        {% endif %}
 +
 +{% for i in page_range %}
 +        {% if page_obj.number == i %}
 +            <span>{{ i }}</span>
 +        {% else %}
 +            <a href="?page={{ i }}">{{ i }}</a>
 +        {% endif %}
 +{% endfor %}
 +
 +        {% if page_obj.has_next %}
 +            <a href="?page={{ page_obj.next_page_number }}">next</a>
 +        {% endif %}
 +    </span>
 +</div>
 +</code>
 +
 +الآن أصبحت لدينا صفحة المقالات هكذا
 +
 +{{ :docs:dj-list-pg.png?480 |أزرار التصفح}}
 +
 +==== عرض create_object ====
 +
 +يقوم هذا العرض يتوليد استمارة form والسماح لك بتعبئتها ثم حفظ الناتج ثم إعادة التوجيه لصفحة ما (مثلا عرض الكائن الذي تم حفظه)
 +
 +يمكنك تمرير المعاملات التالية
 +  * النموذج model في مثالنا Article
 +  * والعنوان الذي سنذهب له بعد الحفظ  post_save_redirect
 +  * هل تحتاج دخول login_required
 +  * اسم القالب template_name
 +
 +تعمل هذه على تمرير form للقالب يمكن إضهاره هكذا
 +<code html>
 +<form action="" method="post">
 +<table>
 +{{ form }}
 +</table>
 +</form>
 +</code>
 +
 +طبعا يمكنك توليد الاستمارة دون الحاجة للعروض العامة من النموذج فهي تستخدم ModelForm الذي يبنى تلقائيا من النموذج هكذا
 +<code python>
 +from django.forms import ModelForm
 +from myapp.models import *
 +
 +class ArticleForm(ModelForm):
 +  class Meta:
 +    model = Article
 +</code>
 +
 +يمكنك تجربة ذلك من خلال 
 +<code bash>
 +python manage.py shell
 +</code>
 +ثم نفذ الكود السابق أو استورده ثم اكتب
 +<code>
 +form=ArticleForm()
 +print form.as_table()
 +</code>
 +
 +لكن الجميل في العروض العامة أنها تلقائيا تنفذ عملية ال validate وتعمل redirect ...إلخ
 +
 +===== القوالب =====
  
docs/django-basics.txt · آخر تعديل: 2015/09/20 14:57 بواسطة alsadi

Donate Powered by PHP Valid HTML5 Valid CSS Driven by DokuWiki