Django:How-to-create-a-basic-blog

از Pythoni.ca

پرش به: ناوبری, جستجو

فهرست مندرجات

فایل های این آموزش

فایل پروژه در این تاپیک ضمیمه شده است .

پیش نیاز ها :

برای دنبال کردن این آموزش نیاز است که:

پایتون نصب باشد .


Django بروی پایتون نصب باشد .


تحلیل

در این مثال می خواهیم با روند کلی فریم ورک Django برای ایجاد برنامه های کاربردی تحت وب آشنا شویم ، برای این منظور مثال ساده ایی چون ساخت یک وبلاگ را در نظر می گیریم .

وبلاگ ما بسیار ساده است ، در زیر ویژگی های این وبلاگ آمده است :

پست های وبلاگ به کمک صفحه admin نوشته می شوند .

پست ها در موضوعاتی دسته بندی می شوند .

این موضوعات نیز به کمک صفحه admin ایجاد می شوند .

در صفحه ی اول وبلاگ می خواهیم لیستی ازعنوان های پست های نوشته شده ی اخیر آورده شود ، که با کلیک بروی هر یک از آنها محتوای آن نشان داده شود .

همچنین می خواهیم در صفحه ی اول وبلاگ لیستی از دسته بندی های موجود نیز آورده شود ، که با کلیک بروی هر دسته بندی ، لیست پست های اخیر مربوط به آن دسته بندی نشان داده شود ، و سپس با کلیک بروی هر پست ، محتوای آن پست نشان داده شود .


ایجاد پروژه

برای شروع پروژه ابتدا پوشه ی دلخواهی ، برای مثال WebPrj ایجاد می کنیم .

سپس از مسیر زیر فایل django-admin.py را در آن کپی می کنیم .


\Python\Lib\site-packages\django\bin\

این فایل (django-admin.py) مقدمات ایجاد پروژه را برای ما فراهم می کند .

اکنون ، خط فرمان را به مسیر پوشه ایی که ساختیم منتقل می کنیم و دستور ریز را اجرا می کنیم :


D:\Working\Django\WebPrj>python django-admin.py startproject weblog

در مقابل گزینه ی startproject ، نام پروژه ایی که قرار است ایجاد کنیم ، را می نویسم . که در اینجا برابر با weblog است .

بعد از اجرای موفق این دستور ، پوشه ایی جدید به نام weblog در داخل پوشه ی WebPrj ایجاد می شود ، در داخل پوشه ی weblog برای راحتی کار، Django بطور خودکار فایلهایی را ایجاد نموده است ، نام این فایل ها به قرار زیر است :


__init__.py
 urls.py
 manage.py
 settings.py


هر یک ازاین فایل ها مفهوم خاصی برای پروژه ی ما دارند :

  • فایل __init__.py که برای مشخص کردن اینکه پوشه ی weblog یک packet هست ، به کار می رود ، مفسر پایتون در صورتی که در داخل پوشه ایی چنین فایلی را ببینید ، با آن پوشه به چشم یک packet نگاه می کند ، چرا که پروژه های Package، Django هستند .

یک package در پایتون ، مجموعه ایی از ماژول هاست و برای گروه بندی فایل های مشابه با یکدیگر و برای جلوگیری از برخورد نام های آنها به کار می رود .


  • فایل urls.py ، این یک فایل پیکربندی است ، در این فایل نحوه ی برخورد با نقاط ورودی سایت شما ، همان آدرس هایی که در browser نوشته می شوند ، تعیین می شود ، و همچنین توابعی که می بایست آن آدرس ها را اداره کنند ، نیز تعیین می شوند . در واقع می توانید این طور تصور کنید که این فایل نگاشتی است مابین url ها و توابع پایتونی (view) ، که آنها را اداره می کنند ، این فایل یکی از ویژگی های قدرتمند Django هست .


  • فایل manage.py ، این فایل اسکریپتی ست که برای مدیریت پروژه تان به کار می رود ، این فایل مشابه به فایل django-admin.py است .


  • فایل settings ، این فایل ، فایل اصلی برای پیکربندی پروژه تان است ، تنظیمات مختلفی از پروژه تان در این فایل قرار می گیرد ، همچون تنظیمات مربوط به پایگاه داده ، زبان سایت ، فعال و غیرفعال کردن برخی از ویژگی های Django و غبره .

اکنون برای آن که ببینیم همه چیز به درستی پیش رفته است ، از فایل manage.py بهره برده و سرور Django را بروی پروژه مان بالا می آوریم ، برای این کار خط فرمان را به مسیر داخل پروژه ی weblog انتقال داده و درخط فرمان دستور زیر را تایپ می کنیم :


D:\Working\Django\WebPrj\weblog>python manage.py runserver

بعد از اجرای این دستور ، در صورتی که همه چیز را بدرستی انجام داده باشیم ، خروجی زیر را ملاحظه می کنیم :


Validating models...
0 errors found

Django version 1.0.2 final, using settings 'weblog.settings'
Development server is running at http://127.0.0.1:8000/
Quit the server with CTRL-BREAK.

وب سرور Django بروی پورت 8000 بروی localhost اجرا شده و منتظر دستورات می ماند . اکنون برای دیدن پروژه ی خود ، با یک مرورگر دلخواه به آدرس زیر رجوع می کنیم :


/http://127.0.0.1:8000

و مشاهد خواهید کرد ، که وب سرور django برای این موفقیت به شما تبریک می گوید  :

تصویر

بسیار خوب ، با کلید Ctrl-C می توانید ، وب سرور را متوقف کنید ، تا ساخت پروژه مان راادامه دهیم . هر پروژه می تواند حاوی چندین Application (برنامه ی کاربردی ) باشد . ما اکنون می خواهیم اولین برنامه ی کاربردی مان را در این پروژه ایجاد کنیم ، برای این کار باز از فایل manage.py پروژه مان استفاده کرده و دستور زیر را در خط فرمان اجرا می کنیم :



D:\Working\Django\WebPrj\weblog>python manage.py startapp blog



این دستور پوشه ی جدیدی به نام blog را در داخل پوشه ی پروژه ی ما (weblog)ایجاد می کند ، همچنین در داخل این پوشه ی جدید ، فایل های کلیدی و لازم که برای ایجاد برنامه ی کاربردی ما ضروری می باشد ، نیز بطور خودکار تولید شده است . فایل های دورن پوشه ی blog عبارتند از :



 __init__.py
 views.py
 models.py


هر یک ازاین فایل ها مفهوم خاصی برای Application ما دارند :

  • فایل views.py ، تمامی view های ما در این فایل قرار می گیرند ، view ها توابعی هستند که وظیفه ی اداره کردن آدرس های مشخصه شده در فایل urls.py را دارند .


  • فایل models.py ، تمامی مدل های داده ایی ما در این فایل قرار می گیرد .


در حاشیه :

برای این که دیدی کلی از این فایل های مطرح شده تا بدین جا داشته باشیم ، اجازه بدهید مثال کوچکی بزنیم ، وقتی شما آدرسی را برای مثال آدرس http://localhost:800/blog را در مرورگر وارد می کنید ، این آدرس (خارج از بحث های داغ پشت صحنه !) ابتدا در فایل urls.py جستجو می شود ، در صورتی که در بین آدرس های وارد شده در این فایل ، همچین آدرسی پیدا شد ، بر اساس نام view ایی که در جلوی آن در فایل urls.py مشخص شده است ، کنترل به یکی از view هایی که در فایل view.py تعریف شده است ، منتقل می شود . در داخل view ، در صورتیکه نیاز باشد ، واکشی های مورد نظر را از پایگاه داده انجام داده ، این واکشی ها با توجه به فایل models.py صورت می گیرد ، در واقع موجودیت ها و داده هایی را که لازم داریم ، از پایگاه داده استخراج کرده و سپس با کمک template (که در ادامه توضیح خواهیم داد ) صفحه خروجی html مربوط به آن لینک را ایجاد کرده ، و نمایش می دهیم (بر می گردانیم) .


بسیار خوب ، اکنون برای اینکه هنگامی که Django پروژ ه ی ما را بروی سرور بالا می آورد ، به او بگوئیم که این application جدیدی را که ایجاد نموده ایم را هم مدنظر بگیرد ، می بایست اسم این برنامه ی کاربردی را به فایل settings.py از پروژه مان اضافه کنیم ، پس فایل settings.py را باز کرده و در بخش زیر، اسم application جدید مان را بصورت weblog.blog ، به مابقی application های از پیش موجود اضافه می کنیم .


INSTALLED_APPS = (
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.sites',
    ' weblog.blog',
)


نوشتن پایگاه داده ی پروژه

همان طور که گفتیم ،در داخل پوشه ی blog ، فایلی به نام models.py قرار دارد ، این فایل ساختار پایگاه داده ما را بیان می کند ، و جداول پایگاه داده ما از روی این فایل ایجاد می شوند .

و همان طور که در بخش تحلیل وبلاگ مشخص شد ، دوموجودیت اصلی وبلاگ ما ، عبارتند از پست (Post) و دسته بندی (Category). هر یک از این موجودیت ها ، دارای ویژگی هایی هستند ، که به ترتیب عبارتند از :

برای موجودیت پست :

عنوان پست (title)، تیتراختصاری پست (slug)، محتوای پست (body) ، تاریخ انتشار پست (date)، دسته بندی پست (category).

برای موجودیت دسته بندی :

عنوان دسته بندی (title)، تیتر اختصاری دسته بندی (slug).

چند نکته :

  • فیلد دسته بندی پست ازموجودیت پست ، بعنوان یک کلید خارجی برای موجودیت دسته بندی است .


  • Django ، کلید اصلی را برای هر موجودیت بصورت خودکار از نوع autonumber تعریف می کند ، از این رو نیازی نیست ما آن را برای هر موجودیت تعریف کنیم .

اکنون ، اطلاعات بالا را بصورت زیر در داخل فایل models.py درج می کنیم :


    class Post(models.Model):
        title = models.CharField(max_length=100, unique=True)
        slug = models.SlugField(max_length=100, unique=True)
        body = models.TextField()
        date = models.DateField(db_index=True, auto_now_add=True)
        category = models.ForeignKey('blog.Category')

    class Category(models.Model):
        title = models.CharField(max_length=100, db_index=True)
        slug = models.SlugField(max_length=100, db_index=True)

  • هر موجودیت در داخل یک کلاس که از کلاس models.Model مشتق شده است ، تعریف می شود ، نوع فیلدهای هر موجودیت از طریق نوع هایی که در ماژول models هستند ، تعریف می شوند ، هر نوع ، آرگومان های اختیاریی می گیرد ، که بر حسب نیاز می بایست تنظیم شوند .


  • فیلد slug ، فیلدی ست که می تواند تنها شامل کاراکترهای عددی ، حروف و خط نشانه باشد ، این فیلد برای استفاده در لینک مستقیم ( permalink ) به یک پست تعریف شده است ، از این رو می بایست یکه (unique) باشد .


علاوه بر فیلدهای داده ایی که هر کلاس تعریف شده در فایل models.py می تواند داشته باشد ، هر کلاس می تواند شامل متدهایی نیز باشد ، دو متدی که ما در اینجا می خواهیم به کلاس مان اضافه کنیم ، عبارتند از : متد __unicode__ ، و متد get_absolute_url ،


  • هرگاه شما متد ()unicode را بروی یک شیء صدا بزنید ، متد __unicode__ از آن شیء فراخوانی می شود ، از اینرو هر گاه ، Django بخواهد شیء ایی را نمایش بدهد ، از این متد استفاده می کند .


  • متد get_absolute_url نحوه ی بدست آوردن url مربوط به یک شیء را مشخص می کند ، هر کلاسی که در فایل models.py تعریف می کنیم ، می تواند دارای یک url باشد . این url می تواند بصورت های مختلفی تعیین شود . و همچنین می توانیم id یک شیء را بعنوان url آن در نظر بگیریم ، ولی برای با معنا بودن لینک ما از فیلد slug کمک می گیریم :

def get_absolute_url(self):
   return  "/%s" %(self.slug)

  • علاوه بر این روش ، می توانیم get_absolute_url را همراه با decorator ایی به نام permalink که در django.db.models هست ، به کار ببریم . برای این منظور می بایست ، get_absolute_url یک چندتایی را که دارای سه عضو است را برگرداند . اولین عضو این چندتایی، نام view ایی ست که در urls.py آمده و فراخوانی شده است ، دومین عضو آن، یک چندتایی از آرگومان های اختیاری ست که به view ارسال می شود . اگر کلا آرگومانی به view ارسال نشود ، نیازی به این آرگومان نیست ، اما اگر آرگومان سوم تنظیم شده باشد ، می بایست این آرگومان بصورت یک چندتایی خالی تنظیم شود. و سومین عضو این چندتایی ، یک دیکشنری از کلید/مقدار هاست که به view ارسال خواهد شد . و اگر نیازی به ارسال این دیکشنری نباشد ، می توان از نوشتن این آرگومان نیز صرف نظر کرد .

بدین ترتیب ، get_absolute_url بر اساس view مورد نظر ، url مربوطه را که در urls.py است برمی گرداند .

پس فایل models.py تکمیل تر شده بصورت زیر است :


from django.db import models
from django.db.models import permalink

# Create your models here.

class Post(models.Model):
    title = models.CharField(max_length=100, unique=True)
    slug = models.SlugField(max_length=100, unique=True)
    body = models.TextField()
    date = models.DateTimeField(db_index=True, auto_now_add=True)
    category = models.ForeignKey('blog.Category')

    def __unicode__(self):
        return '%s' % self.title

    @permalink
    def get_absolute_url(self):
        return ('weblog.blog.views.view_post', None, { 'slug': self.slug })

		
class Category(models.Model):
    title = models.CharField(max_length=100, db_index=True)
    slug = models.SlugField(max_length=100, db_index=True)

    def __unicode__(self):
        return '%s' % self.title

    @permalink
    def get_absolute_url(self):
        return ('weblog.blog.views.view_category', (), { 'slug': self.slug })


اکنون که ساختار جداول پایگاه داده ی ما تکمیل شد ، می بایست از روی این ساختار جداول و فیلدها را در یک پایگاه داده ی مشخصی ذخیره و ایجاد کنیم .

برای این کار ابتدا فایل settings.py که در پوشه ی پروژه (weblog) قرار دارد ، را باز کرده و در قسمت مربوط به تنطیمات پایگاه داده ، نوع پایگاه داده و تنظیمات مربوط به آن را مطابق زیر مشخص می کینم .


DATABASE_ENGINE = 'sqlite3'           # 'postgresql_psycopg2', 'postgresql', 'mysql', 'sqlite3' or 'oracle'.
DATABASE_NAME = 'weblog.db'           # Or path to database file if using sqlite3.
DATABASE_USER = ''             # Not used with sqlite3.
DATABASE_PASSWORD = ''         # Not used with sqlite3.
DATABASE_HOST = ''             # Set to empty string for localhost. Not used with sqlite3.
DATABASE_PORT = ''             # Set to empty string for default. Not used with sqlite3.

برای راحتی کار ، ما در اینجا از پایگاه داده ی sqlite3 استفاده کردیم .

و اسم پایگاه داده را برابر با weblog.db قرار دادیم .

در صورتیکه از پایگاه داده ی دیگری مثل MySql ، استفاده می کنید ، مابقی تنظیمات را نیز که از روی نام شان کاملا مشخص هست ، بدرستی انجام بدهید .

بعد از تعیین تنظمیات کلی پایگاه داده ، برای ساخت و ایجاد جداول در آن ،از فایل manage.py که در پوشه ی پروژه مان قرار دارد ، بصورت زیر کمک می گیریم :


D:\Working\Django\WebPrj\weblog>manage.py syncdb


خروجی این دستور  :


Creating table auth_permission
Creating table auth_group
Creating table auth_user
Creating table auth_message
Creating table django_content_type
Creating table django_session
Creating table django_site
Creating table blog_post
Creating table blog_category

جداول بر اساس تنظیمات ما ایجاد می شوند .

سپس در ادامه ی اجرای این دستور سوالی مبنی بر ایجاد اکانت کاربر با سطح دسترسی مدیریت ، پرسیده می شود ، ما جواب yes را تایپ کرده و اطلاعات درخواستی را وارد می کنیم . این user برای ورود به بخش admin سایت مورد استفاده قرار می گیرد .


You just installed Django's auth system, which means you don't have any superuse
rs defined.
Would you like to create one now? (yes/no): yes
Username: admin
E-mail address: admin@pythoni.ca
Password:
Password (again):
Superuser created successfully.
Installing index for auth.Permission model
Installing index for auth.Message model
Installing index for blog.Post model
Installing index for blog.Category model

D:\Working\Django\WebPrj\weblog>



اکنون ، تمامی جداول مورد نیاز ما بروی پایگاه داده ی مورد نظر ایجاد شده اند .


admin اعجاب انگیز !

یکی از قدرت های Django ، بخش admin آن است . برای فعال کردن این بخش ، لازم است ابتدا فایل settings.py از پروژه مان را باز کرده و خط زیر را به قسمت application های نصب شده اضافه کنیم .



'django.contrib.admin',

به این صورت :


INSTALLED_APPS = (
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.sites',
    'weblog.blog',
    'django.contrib.admin',
)

سپس دستور زیر ( python manage.py syncdb ) را اجرا کرده ، تا جداول مربوطه ایجاد شوند :


D:\Working\Django\WebPrj\weblog>manage.py syncdb
Creating table django_admin_log
Installing index for admin.LogEntry model


و در نهایت فایل urls.py از پروژه مان را باز کرده و خطوطی را که گوش زد کرده ، که برای فعال شدن بخش admin ، می بایست از حالت comment خارج شوند ، را از حالت comment خارج می کنیم .

یعنی این دوخطوط را (که باعث load ماژول admin و فایل های admin.py می شوند) :


from django.contrib import admin
admin.autodiscover()

و همچنین این خط  :


    ,(r'^admin/(.*)', admin.site.root)

خط بالا ، مثالی از نگاشت یک آدرس به یک view است ، اولین آرگومان که از regular expression نیز پشتیبانی می کند ، برای مشخص کردن الگوی آدرس های وارد شده به کار می رود ، برای مثال در اینجا منظور از '(*.)/r'^admin اینست که آدرس وارد شده ، در صورتیکه حتما با کلمه ی admin شروع شود و بدنبال آن بعد از علامت/ هیچ و یا هر تعداد کاراکتری هم بیاید ، مورد قبول این الگو واقع می شود و در نتیجه view ایی ( admin.site.root ) که بعنوان دومین آرگومان در این چندتایی آمده است ، اجرا می شود .

بسیار خوب ، اکنون با توجه به این url ، مشخص هست که از طریق آدرس زیر می توانیم به صفحه ی admin سایت دسترسی پیدا کنیم .


http://127.0.0.1:8000/admin/


پس با دستور manage.py runserver ، سرور django را روشن کرده !، و سپس با مرورگر به آدرس بالا بروید .

تصویر

نام کاربری (admin) و کلمه ی عبوری (123) که در هنگام ایجاد پایگاه داده برای ایجاد اکانت superuser وارده کرده بودید ، را در این فرم وارد کنید تا وارد صفحه ی admin شویم :


تصویر

ما می توانیم علاوه بر مدل هایی که بواسطه ی تنظیمات ما در این صفحه وجود دارند ، کلاس هایی ( موجودیت هایی ) که در فایل models.py تعریف کرده ایم ، را نیز در این صفحه ببینیم . چرا که عملیات درج ، حذف و بروزرسانی بروی فیلدهای آن کلاس دراین صفحه به آسانی صورت می گیرد .

برای این کار می بایست ، ابتدا درداخل پوشه ی برنامه ی کاربردی مان (blog) فایلی به نام admin.py ایجاد کنیم . چنین فایلی هر بار توسط django برای application هایی که نام شان در فایل settings.py آمده است ، چک می شود (admin.autodiscover) ، و در صورتیکه همچنین فایلی باشد ، فیلدهای مشخص شده و مربوط به کلاس آن ها نیز در این صفحه آورده می شود .

خطوط زیر را در فایل admin.py درج نمائید .


from django.contrib import admin
from blog.models import Post, Category

admin.site.register(Post)
admin.site.register(Category)

اکنون ، صفحه admin را درمرورگر ، refresh کنید ، متوجه می شوید که این دو کلاس هم به صفحه ی admin اضافه شده اند ، سعی کنید اولین پست خود را از طریق صفحه ی admin در دسته بندی مورد نظرتون بنویسید . چندین دسته بندی ایجاد کنید و برای هر کدام پست هایی را بنویسید .

به فایل admin.py برگردیم ، ما ابتدا توسط خط زیر ماژول admin را وارد کردیم :


from django.contrib import admin

و سپس از بین مدلهایی که تعریف کردیم ، مدل های Post و Category را وارد می کنیم :


from blog.models import Post, Category

سپس توسط دستورات زیر به ترتیب هر کدام از آنها را به صفحه ی admin ، رجیستر می کنیم .


admin.site.register(Post)
admin.site.register(Category)

همانطور که ملاحظه نمودید ، همین تغییرات کافی ست تا ما مدل های تعریف شده ی خود را در صفحه ی admin داشته باشیم .

اما بااین حال می توانیم ، صفحه ی admin را برای مدل های تعریف شده cusomize تر کنیم ، برای این کار می بایست در فایل admin.py برای هر مدلی که می خواهیم ، یک کلاس که از admin.ModelAdmin مشتق شده است ، ایجاد کنیم ، سپس درتابع admin.site.register ، بعنوان پارامتر اول ، نام مدل و بعنوان پارامتر دوم نام کلاس مربوط به آن مدل را که در اینجا تعریف کرده ایم ، ذکر کنیم.

اما کلاسی که درadmin.py برای هر مدل تعریف می کنیم و از admin.ModelAdmin مشتق شده است ، می تواند دارای ویژگی هایی باشد که برای django معنا و مفهوم خاصی دارد ، ما در اینجا از دو مورد از این ویژگی ها استفاده می کنیم .

اولین ویژگی ، ویژگی exclude است ، که از نام آن هم مشخص است ، فیلدهایی که در لیست آن ذکر شوند ، در صفحه ی admin آورده نمی شوند .

دومین ویژگی ، ویژگی prepopulated_fields ، این ویژگی باعث می شود ، که یک فیلد براساس یک یا چند فیلد دیگر بصورت خودکار پر شود . (این کار در صفحه admin واز طریق فایل urlify.js صورت می گیرد.) برای این منظور مقدار این ویژگی را برابر با یک دیکشنری ایی قرار می دهیم که در داخل این دیکشنری ، کلید همان فیلد پر شونده ی خودکار است ، و مقدار که از نوع یک چندتایی ست ، فیلدهایی هستند که فیلد پرشونده ی خودکار از روی آنها پر می شود .

برای مثال در این جا ، فیلد slug از روی title بصورت خودکار پر می شود . البته تنها کاراکترهای مجاز فیلد title شامل حروف – اعداد و خط نشانه ، بروی فیلد slug منعکس می شوند . که این قضیه براساس rfc مربوط به url ها است .

پس کد کامل کلاس admin.py به این صورت می شود :


from django.contrib import admin
from weblog.blog.models import Post, Category

class PostAdmin(admin.ModelAdmin):
    exclude = ['posted']
    prepopulated_fields = {'slug': ('title',)}

class CategoryAdmin(admin.ModelAdmin):
    prepopulated_fields = {'slug': ('title',)}

admin.site.register(Post, PostAdmin)
admin.site.register(Category, CategoryAdmin)



نوشتن view پروژه

فایل view.py ، جایی ست که تمهیدات لازم را برای نمایش خروجی ( به کمک template ها) بروی مرورگر انجام می دهید .

با توجه به آنچه که در تحلیل وبلاگ گفته شد ، بطور کلی ما می توانیم سه نما (view) را برای سایت مان ایجاد (تصور) کنیم .

  • نمایش آخرین پست ها و دسته بندی های موجود ( index ).
  • نمایش آخرین پست های موجود در یک دسته بندی خاص ( view_category ) .
  • نمایش کامل یک پست (view_post ) .

هر یک از این view ها در داخل یک تابع جداگانه در فایل views.py تعریف می شوند ، پس ما می بایست سه تابع را در آن تعریف کنیم .

فایل views.py را باز کرده و خطوط زیر را در آن درج کنید :



# Create your views here.

from  weblog.blog.models import Post, Category
from django.shortcuts import render_to_response, get_object_or_404

def index(request):
    return render_to_response('index.html', {
        'categories': Category.objects.all(),
        'posts': Post.objects.all()[:5]
    })

def view_post(request, slug):   
    return render_to_response('view_post.html', {
        'post': get_object_or_404(Post, slug=slug)
    })

def view_category(request, slug):
    category = get_object_or_404(Category, slug=slug)
    posts =  Post.objects.filter(category=category)[:5]
    return render_to_response('view_category.html', {
        'category' : category,
        'posts': posts
    }
	)


توضیح کدهای مربوط به views.py :

در اولین خط ما مدل هایی (Post, Category) که به داده های آن هااحتیاج داریم ، را import می کنیم .


from  weblog.blog.models import Post, Category

در دومین خط ، دو تابع به نام های render_to_response و get_object_or_404 را وارد می کنیم .

  • تابع get_object_or_404 برای واکشی داده از داخل پایگاه داده به کار می رود ، بطوریکه اگر آن داده درون پایگاه داده موجود نباشد ، بطور توکار استثناء رخ داده شده را کنترل کرده و صفحه ی خطای 404 را نمایش می دهد ، و اگر داده در جدول مورد نظر از پایگاه داده موجود باشد ، آن را برمی گرداند ، این تابع یکی از shortcut هایی ست که django برای راحتی کار در اختیار ما قرار دارد .


  • تابع render_to_response ، این تابع برای تولید خروجی قابل نمایش بروی صفحه ی نمایش مرورگر به کار می رود ، این تابع در صورت لزوم ، داده هایی را که از پایگاه داده استخراج شده است را به template مورد نظر فرستاده ، و بعد از اینکه صفحه ی template ، بر اساس این داده ها render شد ، خروجی حاصل را که کدهای html قابل نمایش بروی مرورگر است ، به مرورگر ارسال می کند ، اولین آرگومان این تابع ، نام template مورد نظر و دومین آرگومان آن ، دیکشنری از متغیرهای داده ایی ست که قرار است به template ارسال شود . این تابع نیز یکی دیگر از آن shortcut هایی ست که برای راحتی کار در اختیار ما قرار دارد .

from django.shortcuts import render_to_response, get_object_or_404


اولین تابع و اولین view ما ، index نام دارد ، توابع view می بایست حداقل دارای یک آرگومان باشند ، که دراینجا به نام request مشخص شده است ، و حاوی تمامی اطلاعات مروگر کاربر نظیر : Post ، Get و غیره است ،چرا که هنگامی که کاربری از طریق url ایی به نمایی وارد می شود ، این اطلاعات نیز در قالب اولین آرگومان به view مورد نظر منتقل می شوند .

دستور ()Category.objects.all ، تمامی داده های موجود در جدول Category را از پایگاه داده استخراج می کند . و دستور Post.objects.all()[:5] تنها 5 داده ی انتهایی از داده های موجود در جدول Post را استخراج می کند .

سپس خروجی این دستوربه ترتیب در متغیرهای categories و posts قرار می گیرد ، و توسط تابع render_to_response به template ایی به نام index.html ( که ما در ادامه آن را خواهیم نوشت ) ارسال می کند ، تا پس از render شدن با این متغیرها ، خروجی به سمت مروگر برگردانده شود .

پس به این ترتیب با اجرای این view ما لیستی از تمام دسته بندی های موجود و لیستی از 5 پست اخیر را خواهیم داشت .


def index(request):
    return render_to_response('index.html', {
        'categories': Category.objects.all(),
        'posts': Post.objects.all()[:5]
    })

فایل template مشخص شده برای این view که قرار است در ادامه نوشته شود ، به نام 'index.html' تعیین شده است .


url مربوط به این view در فایل urls.py :

ما در فایل urls.py ، الگوی زیر را برای این view تنظیم می کنیم :


    (r'^$', 'weblog. blog.views.index'),


به این ترتیب در صورتی که در مرورگر آدرس /127.0.0.1:8000 وارد شود ، ما وارد این view می شویم .

دومین view ما ، تابع view_post نام دارد :


def view_post(request, slug):   
    return render_to_response('view_post.html', {
        'post': get_object_or_404(Post, slug=slug)
    })


همان طور که می بینید این view علاوه بر آرگومان request ، آرگومان دیگری به نام slug می پذیرد ، این آرگومان با توجه به الگویی که در فایل urls.py برای این view تنظیم شده است ، از طریق آدرسی که در مرورگر تایپ می شود به این view ارسال می شود .

در اینجا تابع get_object_or_404 ، بعنوان اولین آرگومان مدل داده ایی را دریافت کرده است و از آرگومان دوم برای query گرفتن بروی آن استفاده می کند . در صورتی که آرگومان دوم ( slug ) با مقدار داده شده در جدول Blog موجود باشد ، آن رکورد برگردانده می شود ، در غیر اینصورت صفحه ی خطای 404 نمایش داده می شود .

فایل template مشخص شده برای این view که قرار است در ادامه نوشته شود ، به نام 'view_post.html' تعیین شده است .


url مربوط به این view در فایل urls.py :

در فایل urls.py ، الگوی زیر را برای این view تنظیم می کنیم :


(r'^blog/view/(?P<slug>[^\.]+).htm','weblog.blog.views.view_post'),


تنها تکه ی جدید در این الگو ، عبارت(+[.\^P<slug>?)است ، منظور ازاین عبارت ، در این الگو اینست که درآدرسی که در مرورگر وارد می شود ، ما بین blog/view/ و htm. هر چیزی می تواند بیاید ، و این چیز ! ، در قالب یک متغیر به نام slug به تابع view_post انتقال داده می شود ( بعنوان دومین آرگومان ) .

پس در واقع اگر ما در مرورگر آدرس زیر را وارد کنیم :


http://127.0.0.1:8000/blog/view/tiltle_01.htm


این آدرس خود را با الگوی زیر مطابق می بیند :


(r'^blog/view/(?P<slug>[^\.]+).htm','weblog. blog.views.view_post'),


در نتیجه ، view_post ، اجرا می شود ، و slug که حاوی tiltle_01 است ، بعنوان آرگومان دوم به این تابع ارسال می شود.

البته کاملا مشخص است که پسوند htm. ایی که ما در الگو قید کردیم ، می تواند برداشته شودو یا با هر پسوند دیگری جایگزین شود، در اینصورت آدرسی که در مرورگر نوشته می شود می بایست از این الگو جدید پیروی کند .

آخرین view ، تابع view_category نام دارد ، که با توضیحات بالا ، کد جدید در این تابع دستور (Post.objects.filter(category=category است ،ابن دستور تنها آن رکوردهایی از جدول Post را برمی گرداند که فیلد category آنها برابر با category مشخص شده بعنوان آرگومان باشد ، در واقع لیستی از پست هایی را که در یک دسته بندی خاص قرار دارند را برمی گرداند .

فایل template مشخص شده برای این view که قرار است در ادامه نوشته شود ، به نام 'view_category.html' تعیین شده است .


def view_category(request, slug):
    category = get_object_or_404(Category, slug=slug)
    posts =  Post.objects.filter(category=category)[:5]
    return render_to_response('view_category.html', {
        'category' : category,
        'posts': posts
    }
	)


url مربوط به این view در فایل urls.py :

در فایل urls.py ، الگوی زیر را برای این view تنظیم می کنیم :


    (r'^blog/category/(?P<slug>[^\.]+).html','blog.weblog.views.view_category')


  • دستوراتی نظیر Category.objects.all، Post.objects.all،get_object_or_404 ،Post.objects.filter که در view برای استخراج داده از پایگاه داده به کار بردیم ، در عمل همان دستور sql ایی هستند که django بصورت انتزاعی ، در قالبی جدید در اختیار ما قرار می دهد ، ما می توانیم ازاین دستورات برای هر گونه query گرفتن بروی پایگاه داده استفاده کنیم ، برای لیست کامل آن ها به مستندات django رجوع کنیم . البته بطور مستقیم هم می توانیم از دستورات sql استفاده کنیم.

پس فایل urls.py بطور کلی بصورت زیر است :


from django.conf.urls.defaults import *

# Uncomment the next two lines to enable the admin:
from django.contrib import admin
admin.autodiscover()

urlpatterns = patterns('',
    # Example:
    # (r'^weblog/', include('weblog.foo.urls')),

    # Uncomment the admin/doc line below and add 'django.contrib.admindocs' 
    # to INSTALLED_APPS to enable admin documentation:
    # (r'^admin/doc/', include('django.contrib.admindocs.urls')),

    # Uncomment the next line to enable the admin:
    (r'^admin/(.*)', admin.site.root),
	#Blog Url
    (r'^$', 'weblog.blog.views.index'),
    (r'^blog/view/(?P<slug>[^\.]+).htm','weblog.blog.views.view_post'),
    (r'^blog/category/(?P<slug>[^\.]+).html','weblog.blog.views.view_category')
)


نوشتن template های پروژه

سیستم templating در django واقعا بسیار قوی ست ، ولی ما در اینجا درحد نیازمان از آن استفاده می کنیم.

همان طور که در view های نوشته شده ، مشخص شد ، ما نیاز داریم که سه template به نام های index.html ، view_post.html ، view_category.html تعریف کنیم .

  • template ها ، شکل و نمایش (presentation) صفحات ما را می سازند .
  • template ها می توانند از css و js و تگ های html ، بهره ببرند .
  • template ها از وراثت پشتیبانی می کنند .
  • دو ویژگی مورد استفاده در template ها ، استفاده از tag ها ، و استفاده از filter ها است .
  • template ها در نهایت چیزی جز کد html نیستند ، پس می بایست به مانند کدهای html معتبر باشند .


همانطور که گفتیم ، template ها از وراثت پشتیبانی می کنند ، نگاهی که django به وارثت در template ها دارد ، دقیقا برعکس حالتی ست که با دستور incude در زبانهای تحت وبی همچون php برخورد می کنیم . در اینجا ، template والد ، دارای حفره هایی ست که این حفره ها توسط template های فرزند (در صورت نیاز) پر می شوند .

ما می خواهیم از قابلیت وراثت django در اینجا استفاده کنیم ، در نتیجه ، درکنار سه template موجود ، template جدیدی به نام base.html (والد) هم خواهیم داشت که بدنه اصلی template ما است ، و بخش هایی از آن توسط دیگر template ها ( فرزند ها ) پر می شوند .

ابتدا پوشه ی جدیدی به نام templates را در داخل پوشه ی پروژه (weblog) و در کنار پوشه ی برنامه ی کاربردی مان (blog) ایجاد کنید .

در داخل پوشه ی templates ، فایل هایی با اسامی گفته شده ، ایجاد کنید ، سپس کدهای آن ها را بر اساس آنچه در ادامه می آید ، بنویسید .

سپس می بایست مسیر پوشه ی template را در فایل settings.py از پروژه تعیین کنیم ، برای این کار فایل settings.py را بازکرده و در بخش مربوط به مسیر template ، مسیر کامل پوشه ی template پروژه را وارد کنید :


TEMPLATE_DIRS = (
    # Put strings here, like "/home/html/django_templates" or "C:/www/django/templates".
    # Always use forward slashes, even on Windows.
    # Don't forget to use absolute paths, not relative paths.
	"D:/working/django/WebPrj/weblog/templates",
)


والد اصلی template های ما ، فایل base.html است :


'''base.html'''

    <html>
        <head>
            <title>{% block head_title %}Welcome to my blog{% endblock %}</title>
        </head>
        <body>
            <h1>{% block title %}Welcome to my block{% endblock %}</h1>
            {% block content %}

            {% endblock %}
        </body>
    </html>

همان طور که ملاحظه می کنید ، template ها ساختاری شبیه به کدهای html دارند ، و می توانیم از کدهای html در template ها استفاده کنیم . کدهای html بخش static مربوط به template ما را می سازند ، برای پیچیده نشدن template ها ، Django از کدنویسی رایج کدهای پایتون در این قسمت جلوگیری می کند ، اما دو ویژگی شاخصی را که در داخل template ها در اختیار ما قرار می دهد ، عبارتست از tag ، و filter . tag ها در داخل جفت عبارت {%  %} به کار گرفته می شوند .

filter ها در داخل جفت عبارت {{ }} به کار گرفته می شوند .

ما در این جا تنها از tag ها استفاده می کنیم .

django از شمار زیادی از tag ها و filter های توکار پشتیبانی می کند ، لیست آن ها را می توانید در مستندات django ملاحظه کنید . همچین شما خود می توانید tag و filter دلخواه خودتان را در صورت لزوم بنویسید .

یکی از tag هایی که در اینجا به کار رفته است ، تگ block است :

template والد :


{% block head_title %}
Welcome to my blog
{% endblock %}


این tag ، در وراثت کاربرد دارد. بدین صورت که در template والد ، چنین بلوکی ، (همچون کد بالا) تعریف می شود ، و در نتیجه در صورتی که در template فرزند ، (همچون کد پائین ) ، template والد بعنوان والد این فرزند تعیین شود (توسط تگ extends انجام می شود ) ، آن گاه در صورتی که بلوکی با همین اسم ، در template فرزند تعریف شود ، محتوای بلوک فرزند جای محتوای بلوک والد را پر خواهد کرد :

template فرزند :


{% extends 'base.html' %} 
{% block head_title %}
Viewing category 
{{category.title}}
{% endblock %}



نکاتی در مورد تگ block :

  • می بایست نام تگ block ، در جلوی آن بصورت یک رشته آورده شود . ( برای مثال در اینجا head_title است )
  • هر تگ block می بایست با تگ endblock بسته شود .
  • بصورت اختیاری می توان نام تگ را در جلوی تگ endblock هم نوشت .


تگ extends نیز که دربالا توضیح داده شد ، برای بیان این که یک template فرزند template دیگر است به کار می رود . در جلوی این تگ می بایست اسم تگ مربوطه (والدش) نوشته شود ( که دراینجا برابر با base.html است )

دو تگ پرکاربرد دیگر که ما در این مثال نیز استفاده کرده ایم ، تگ if و تگ for است .

تگ for ، برای پیمایش بروی یک متغیر تکرار شونده (بطور معمول یک list ) ، به کار می رود .


        {% for category in categories %}
            <li><a href=javascript:void(0);        {% endfor %}


نکاتی در مورد تگ for  :

  • به یک آرگومان تکرار شونده نیاز دارد .
  • می بایست با تگ endfor بسته شود .

تگ بعدی ، تگ if است ، در صورتی که آرگومان داده شده به آن True ارزیابی شود ، بخشی از کد template را که در بلوک خود دارد را اجرا می کند .



    {% if categories %}
        <ul>
        {% for category in categories %}
            <li><a href=javascript:void(0);        {% endfor %}
        </ul>
    {% else %}
        <p>There are no posts.</p>
    {% endif %}


نکاتی در مورد تگ if :

  • ما تگی به اسم else-if نداریم ، اما می توانید از if های تو در تو استفاده کنید .
  • می توان از and و or برای ایجاد شرط های چندگانه استفاده کرد .
  • می توان از not برای بررسی نادرستی شرط در if استفاده کرد .
  • می بایست با تگ endif بسته شود .

اشیاء و داده هایی که از طریق view به template ارسال شده اند ، در template معتبر هستند ، و می توان درداخل tag ها با همان اسمی که از view به template ارسال شده اند ، به آن ها مراجعه کرد .

برای جایگزین کردن مقدار یک متغیر در داخل کدهای html ، آن مقدار را در داخل جفت علامت {{ }} قرار می دهیم .

برای صدا زدن متدی از یک شیء ارسالی به template نیازی به نوشتن جفت پرانتز آن نیست .

Django سعی می کند ، کد نویسی را به view انتقال دهد و تا حد امکان template ها را پیچیده نکند .

در ادامه کدهای مربوط به سه template دیگر آمده است :


index.html


{% extends 'base.html' %}
{% block title %}Welcome to my blog{% endblock %}

{% block content %}

    <h2>Posts</h2>
    {% if posts %}
        <ul>
        {% for post in posts %}
            <li><a href=javascript:void(0);        {% endfor %}
        </ul>
    {% else %}
        <p>There are no posts.</p>
    {% endif %}
    <h2>Categories</h2>
    {% if categories %}
        <ul>
        {% for category in categories %}
            <li><a href=javascript:void(0);        {% endfor %}
        </ul>
    {% else %}
        <p>There are no posts.</p>
    {% endif %}
{% endblock %}


view_post.html


    {% extends 'base.html' %} 
    {% block head_title %}{{post.title}}{% endblock %}
    {% block title %}{{post.title}}{% endblock %}

    {% block content %}
        {{post.body}}
    {% endblock %}


view_category.html


    {% extends 'base.html' %} 
    {% block head_title %}Viewing category {{category.title}}{% endblock %}
    {% block title %}{{category.title}}{% endblock %}

    {% block content %}
        {% if posts %}
            <ul>
            {% for post in posts %}
                <li><a href=javascript:void(0);            {% endfor %}
            </ul>
        {% else %}
            <p>There are no posts.</p>
        {% endif %}
    {% endblock %}


بسیار خوب ، اکنون ، با اتمام template به پایان ساخت وبلاگ رسیدیم ، سرور django را بروی پروژه تان بالا بیاورید و سپس با مرورگر به صفحه اول سایت بروید ، در صورتی که پست هایی را از طریق صفحه ادمین نوشته باشید ، و دسته بندی آن ها را نیز مشخص کرده باشید ، می توانید در صفحه اول وبلاگ تان ، لیستی از پست های اخیر و لیست دسته بندی های موجود را ملاحظه کنید ، سعی کنید به کاوش در وبلاگ تان بپردازید ، کم و کاستی های آن را یادداشت کنید و در صورت لزوم تغییرات لازم را اعمال کنید .

تصویر

نتیجه گیری

ما دراین آموزش خواستیم ، بصورت کلی با روند تولید برنامه های کاربردی تحت وب توسط فریم ورک django آشنا شویم . تا جائی که توانستیم از جزئیات فاصله گرفتیم و سعی کردیم به جای مطرح کردن جزئیات خط کلی کاردرذهن شما تداعی شود . هر کدام از مباحث مطرح شده همچون Views ، Models ، Urls ، Admin ، Template و ... جزئیات فراوانی دارند ، و حتی django دارای ویژگی های بسیاری ست که اصلا دراینجا اسمی از آن ها برده نشد . البته شاید این روندی که در اینجا مطرح شد ، برای شما کمی طولانی به نظر برسد ، اما یکبار که بخوبی این کار را انجام بدهید ، برای مراحل بعدی ، براحتی و حتی در کمتر از نیم ساعت قادر خواهید بود ، این روند را تکرار کنید .

فایل پروژه به این تاپیک ضمیمه شده است ، برای استفاده نیاز دارید که مسیر template را در فایل settings.py به همان گونه که توضیح داده شد ، بدرستی بروی سیستم تان تنظیم کنید .


[ لینک های اصلی : نقل شده با کمی دخل ، تصرف و ...]


how-to-create-a-basic-blog-in-django

starting-your-applications

defining-your-models.html

configuring-the-automatic-admin

writing-the-views-defining-your-urls

writing-the-templates