جنگو یک فریمورک وب است که برمبنای پایتون نوشته شده.

نصب و راه‌اندازی سرویس جنگو

ابتدا باید ابزارهای مورد نیاز برای نصب پایتون را با APT بگیرید:

sudo apt-get install python-setuptools

از اسکریپت easyinstall برای نصب virtualenv استفاده کنید. این امکان وجود دارد که به جای استفاده از ویرچوال‌انو، جنگو و وب‌سرور و بقیه ابزارهای مورد نیاز را به طور مستقیم روی خود سرور نصب کنید ولی استفاده از این متد به شما یک sandbox می‌دهد و شما هر کاری بکنید درون همین sandbox می‌کنید برای همین مثلا درصورت خرابکاری، با حذف دایرکتوری ویرچوال‌انو تمام تنظیمات و برنامه‌های مرتبط به آن نیز حذف می‌شود و برای همین این متد safeتر است. در نسخه ژانویه ۲۰۱۴ ویرچوال‌انو یک باگ وجود دارد برای همین با دستور زیر نسخه ۱.۱۰.۱ را نصب کنید:

sudo easy_install virtualenv==1.10.1

حالا باید از دستور virtualenv برای ساخت یک فولدر که همه چیز از جمله خود جنگو و وب‌سرور و دیتابیس و … در آن نصب شود، استفاده کنیم. –no-site-packages می‌گوید جنگوی جدیدی که می‌خواهیم راه بندازیم نباید هیچکدام از ماژول‌های جنگوی گلوبالی که روی خود سیستم نصب شده (اگر نصب باشد) را داشته باشد و می‌خواهیم جنگو را فرام اسکرچ بالا بیاوریم و هیچ دیتای اضافی وارد آن نشود. به جای virtualenvdirname نام مورد نظر برای فولدر یا نام ویرچوال‌انو را مینویسیم:

virtualenv --no-site-packages virtualenvdirname

بعد از وارد کردن دستور بالا pip در این دایرکتوری نصب می‌شود. برای استفاده از کامند‌های pip و بقیه کامند‌های ستاپ باید ویرچوال اینوایرومنت را اکتیویت کنیم:

source virtualenvdirname/bin/activate

الان زمان نصب جنگو هست. به روت ویرچوال اینوایرومنت وارد شوید:

cd virtualdirname

دقت کنید دیگر به استفاده از sudo نیازی نیست زیرا شما در sandboxتان روت هستید و برای همین این روش safe هست. با دستور زیر جنگو را نصب کنید:

easy_install Django

بعد از این مرحله فایل django-admin.py به شاخه bin ویرچوال‌انوتان اضافه می‌شود. حالا باید پروژه بسازید برای ساخت پروژه از دستور زیر استفاده کنید:

django-admin.py startproject projectname

حالا اگر ls بگیرید مشاهده می‌کنید که دایرکتوری پروژه در ویرچوال‌انو ساخته شد. کانفیگ‌های مربوط به وب‌سرور جنگو در فایل manage.py در روت پروژه قرار میگیرد. برای استارت کردن سرویس از دستور زیر استفاده کنید:

python manage.py runserver

دستور بالا بعد از اجرا به شما یک آدرس می‌دهد که می‌توانید صفحات پروژه را از طریق آن مشاهده کنید. برای متوقف کردن و بیرون آمدن از virtualenv از دستور زیر استفاده کنید:

deactivate

بررسی کانفیگ فریمورک جنگو

در مسیر زیر یک فایل تنظیمات با نام settings.py قرار دارد. می‌خواهیم تنظیمات مربوط به دیتابیس و تایم‌زون و زبان و … را در این فایل بررسی کنیم:

~/virtualenvdirname/projectname/projectname

اگر جایی که DATABASES مقداردهی شده را نگاه کنید متوجه می‌شوید که جنگو از sqlite استفاده می‌کند و نیازی به نصب یک پکیج دیتابیس مجزا برای آن نیست. می‌توانید مواردی مانند HOST و USER و PASSWORD و PORT و … را هم اضافه کنید. متغیرهای LANGUAGE_CODE و TIME_ZONE هم از همین فایل قابل تغییر هستند.

نصب و نوشتن کلاس article

قدم بعد نصب برنامه article در پروژه ساخته شده هست که به ما امکان ساختن یک سایت خیلی ساده را می‌دهد:

python manage.py startapp article

با اجرای این دستور یک دایرکتوری در روت پروژه به نام article ساخته می‌شود. مزیت این دایرکتوری اینست که اگر بعدها همین دایرکتوری را وارد یک پروژه دیگر کنید می‌توانید از آن استفاده کنید و این به معنی code reuse هست. در داخل دایرکتوری article یک فایل به نام init.py با حجم ۰ هست که به پایتون می‌فهماند این دایرکتوری و فایل‌های درون آن یک ماژول هستند و می‌شود این ماژول را هر جایی ایمپورت کرد. tests.py برای نوشتن unit test ها استفاده می‌شود. در ادامه فایل models.py را باز کنید. خط اول این فایل می‌گوید که مدل‌های داخل دیتابیس خود جنگو را ایمپورت کند. با این خط کاری نداریم. می‌خواهیم برای نمونه یک کلاس برای مطالب سایتمان بنویسیم. در اینجا من یک کلاس نمونه نوشتم و در انتهای آن خط به خط توضیح دادم چیکار کردم.

class Article(models.Model):
    title = models.CharField(max_length=200)
    body = models.TextField()
    pub_date = models.DateTimeField('date published')
    likes = models.IntegerField()

در خط اول کلاس روی آن اسم میگذاریم و می‌گوییم که این کلاس خصوصیات models.Model را ارث‌بری می‌کند. یک آرتیکل یک عنوان دارد یک بادی تعداد لایک دارد پس باید متغیرهای آن و تایپشان تعریف شوند. در اینجا نوع تایتل، کاراکتر با طول حداکثر ۲۰۰ نوع بادی، تکست‌فیلد نوع تاریخ انتشار، دیت‌تایم و نوع تعداد لایک‌ها، اینتیجر تعریف شده. فهرست کامل نوع‌ها مثل تکست‌فیلد و … و آرگومان‌هایشان در سایت جنگو موجود است.

ساخت دیتابیس برای پروژه

تا اینجا در فایل کانفیگ به نشانی دیتابیس ارجاع داده‌ایم اما در آن نشانی دیتایبسی نداریم و باید با کامند زیر به جنگو بگوییم دیتابیس را بسازد و اطلاعات آن را سینک کند:

python manage.py syncdb

دقت کنید دستوراتی نظیر دستور بالا وقتی قابل اجرا هستند که در دایرکتوری روت پروژه باشید و ویرچوال‌انو را فعال کرده باشید درغیر اینصورت با پیغام خطای «این دستور وجود ندارد» یا «شما مجوز اجرای آن را ندارید» مواجه می‌شوید. پس از اجرای این دستور اطلاعات زیر از شما خواسته می‌شود:

You have installed Django's auth system, and don't have any superusers defined.
Would you like to create one now? (yes/no):

جواب:

yes

بعد هم یوزرنیم و پسورد و ایمیل را انتخاب کنید. حالا دیتابیس ساخته شده. فایل db.sqlite3 را در روت پروژه می‌توانید ببینید. برای مشاهده محتویات این فایل پیشنهاد می‌شود برنامهٔ SQLite Database Browser را نصب کرده باشید. همچنین برای ویرایش فایل‌های پایتون پیشنهاد می‌شود ادیتور pycharm را حتما نصب کرده باشید. اگر دیتابیس را با برنامه نامبرده باز کنید تعدادی table مانند جدول کاربران و سیژن‌ها و … را مشاهده خواهید کرد ولی جدول مربوط به article در اینجا حضور ندارد.

تعریف جدول کلاس آرتیکل در دیتابیس

به فایل setting.py بروید و با اضافه کردن خط زیر درون INSTALLED_APPS به سیستم بفهمانید که یک برنامه به نام article نصب کرده‌اید:

'article'.

سپس با دستور سینک دوباره سینک کنید:

python manage.py syncdb

اگر بعد از اجرای این دستور با این پیغام خطا مواجه شدید:

Operations to perform:
  Apply all migrations: admin, contenttypes, auth, sessions
Running migrations:
  No migrations to apply.
  Your models have changes that are not yet reflected in a migration, and so won't be applied.
  Run 'manage.py makemigrations' to make new migrations, and then re-run 'manage.py migrate' to apply them.

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

python manage.py makemigrations
python manage.py migrate

سپس با دستور سینک دوباره سینک کنید:

python manage.py syncdb

سپس دیتابیس بروزر را باز کنید. جدول article_article به آن اضافه شده. نکته قابل توجه اینست که این دیتابیس بدون نوشتن کوعری اس‌کیو‌ال انجام شده است. با دستور زیر میتوانید دستور create table ساخت همین جدول را مشاهده کنید:

python manage.py sql article

اگر در فیلدهای مربوط به article در کلاسی که داخل model نوشتید تغییری ایجاد کنید سینک کردن این تغییر کار راحتی نیست. با دستور زیر این امر امکان‌پذیر است:

python manage.py reset article

شل جنگو

یکی از امکانات جالب جنگو شل آنست. با وصل شدن به شل جنگو می‌شود روی models ها کار کرد. برای ورود به شل:

python manage.py shell

در اینجا باید کلاس Article از فایل article.models را به شل ایمپورت کنیم تا روی آن کار انجام دهیم:

>>> from article.models import Article

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

>>> Article.objects.all()
[]

برای اینکه بتوانیم درون برنامه‌ها timestamp جنریت کنیم از دستور زیر استفاده کنیم:

>>> from django.utils import timezone

حالا یک آبجکت article میسازیم و درون متغیر a میریزیم:

>>> a = Article(title="test 1", body="blah", pub_date=timezone.now(), likes=0)

اگر بزنید a به شما نوع آن که آبجکت هست را نشان می‌دهد:

>>> a
<Article: Article object>

برای سیو کردن آبجکت:

>>> a.save()

برای دیدن id آبجکت سیو شده:

>>> a.id
1

به همین ترتیب می‌توانید یک آرتیکل دیگر بسازید. سیستم به طور خودکار id دو را به آن نسبت می‌دهد. آرتیکل بعدی ۳ و … الی آخر. اگر دستور زیر را بزنید حالا کل objectهای article درون دیتابیس را به شما نشان می‌دهد:

>>> Article.objects.all()
[<Article: Article object>, <Article: Article object>, <Article: Article object>]

در اینجا می‌خواهیم در خروجی دستور بالا هنگام نمایش آرتیکل‌ها به جای Article object به ما عنوان آرتیکل را نمایش دهد. برای این منظور باید به کلاس اضافه کنیم که به جای خود آبجکت ساخته شده در return statement خود مقدار title را به صورت unicode برگرداند تا شل آن را به صورت آبجکت نبیند و بتواند تایتل را نمایش دهد و این کارمان را راحت می‌کند. برای این منظور با Ctrl + D از شل خارج شوید. فایل models.py را باز کنید و به انتهای کلاس این خط را اضافه کنید:

def __unicode__(self):
    return self.title

حالا دوباره به شل وارد شوید و دستور زیر را بزنید. خروجی به این ترتیب خواهد بود:

>>> Article.objects.all()
[<Article: title 1>, <Article: title 2>, <Article: title 3>]