سلام بچه ها امیدوارم خوب باشین.
تصمیم گرفتم راجع به جنگو یه آموزش tutorial گونه داشته باشیم بعدش بریم سراغ Django Rest Framework یا همون به اختصار DRF تا مبحث API رو ادامه بدیم و در واقع Restful رو آموزش بدیم.
اما اینجا فعلا با جنگو آشنا میشیم بعدشم تو یه مطلب دیگه میریم سراغ ORM جنگو.
درواقع تفاوتی که Frame Work با Library داره اینه:
لایبرری ها معمولا خیلی کوچیکتر از فریم ورک هستن مثل requests, selenium, pandas و ...
لایبرری معمولا برای این بوجود اومده که بتونیم باهاش یه مشکل خاص رو حل کنیم
از اونطرف Frame Work یه ابزاری هست برای توسعه سیستم ها و برنامه ها و حتی ممکنه در یک فرم ورک چندین کتابخونه وجود داشته باشه
جنگو یه Frame Work پایتونی هستش که میشه ازش به عنوان back-end پروژه که فرضا یه وبسایت هستش، استفاده کرد.
گرچه جنگو میتونه درون خودش front-end هم جا بده ولی معمولا اینروزا اینکارو نمیکنن و بیشتر به عنوان API از DRF استفاده میکنند.
خب حالا اصلا چرا از Frame Work ای مثل Django استفاده میکنیم ؟!
خودمون نمیتونیم با پایتون انجامش بدیم ؟
خب قطعا این سوال بجایی هست و از قضا شدنی هم هست! ولی مسئله اینه، چرا باید دوباره چرخ رو اختراع کنیم ؟
Don't Reinvent the Wheel!
بعد هم اینکه یچیزی مثل Django تمام کارهای مورد نیاز مارو از قبل تو خودش داره فقط ما ازش استفاده میکنیم :)
و خب مشخصا خیلی حرفه ای تر، ایمن تر از چیزی هست که ما بخوایم از صفر بنویسیم و بسازیم.
فرضا برای مبحث وب، اینکه Request چجوری میاد، Response چجوری میره و هندل کردن اینا به ما مستقیما مربوط نیست، چون خود جنگو اینکار هارو میکنه
حتی بصورت پیشفرض وب سرور لوکال هم داره و پنل ادمین
تک تک اینا میتونه مسائل وقت گیر و پر دردسری باشه برامون اگه بخوایم از صفر بنویسیم :)
اول باید با pip که پکیج منیجر پایتون هستش، django رو نصب کنید
python -m pip install django
بعدش باید یک پروژه بسازیم با جنگو :)
django-admin startproject movie_site .
یه دایرکتوری به اسم movie_site براتون ساخته شده الان جایی که هستید
و همینطور یک فایل به اسم manage.py
من بعد هرکاری که میتونستیم با کامند django-admin بکنیم رو با python manage.py انجام میدیم
مثل اجرا کردن سرور(runserver)، ساخت فایل تغییرات دیتابیس (makemigrations)، اعمال تغییرات روی دیتابیس(migrate)، ساخت سوپریوزر(createsuperuse) و ...
محتویات دایرکتوری movie_site هم بدین شکل هست:
movie_site (directory)
ماژول اول برای اینه که پایتون بفهمه این دایرکتوری یک Package هست
دو ماژول بعدی یعنی wsgi و asgi برای deployment هست که فعلا بهش کاری نداریم
ماژول چهارم یعنی urls.py برای مشخص کردن url های پروژه ما هست
و آخریش settings.py برای تنظیمات پروژه هستش.
معماری جنگو MVT هستش مثل همون MVC معروف، منتهی با مقداری تغییرات
M --> Model
V --> View
T --> Template
مدل تو جنگو در واقع برای ساخت table های دیتابیس و مشخص کردن field ها و ویژگی هاشون هست!
یعنی همون دیتا بیس sql ای جنگو :)
فرضا میخوایم یک table ای داشته باشیم که اسمش movie یعنی فیلم هست و توش یکسری اطلاعات راجع به فیلم ها ذخیره کنیم
تو جنگو برای اینکار باید تو models.py این رو به عنوان یک entity یا object یا همون class تعریف کنیم.
خیلی خلاصه و مفید:
این ماژولم برای هندل کردن http request ها هستش
درخواست هایی که به وب سرور ما فرستاده میشه از طریق url
اینکه چه متدی داره http request و بر اساس اون چه فانکشنی رو اجرا کنه و ...
پ.ن: اگر با http/ http methods آشنا نیستید میتونید اینجا درباره ش مطالعه کنید
این بخش در واقع نحوه نمایش اطلاعات به کاربر هستش.
یعنی فایل html توش استفاده میشه و با django web template engine که jinja هستش میتونیم با یه سینتکس خاصی بهش data رو بدیم به صورت dynamic به کاربر بده.
خب این توضیحات ابتدایی بود برای شناخت بهتر معماری پروژه های جنگو
حالا باید به این اشاره کنیم که ما یه پروژه ساختیم ولی همه کد رو توی اون نباید بنویسیم
بر اساس نیاز و شناخت یکسری موارد که تو این پست نمیگنجه، باید برای هر بخش از برنامه، یک app بسازیم
مثلا اینجا ما نیاز داریم یه app به اسم movies بسازیم.
اینشکلی:
python manage.py startapp movies
الان یه دایرکتوری جدید داریم به اسم movies
اگه یه نگاهی بهش بنداریم میبینیم که شامل این ماژول ها هستش:
movies (directory)
و یک دایرکتوری به اسم migrations
این مایگریشن برای اینه که ما هروقت تغییراتی توی مدل هامون میدیم، یه کامندی بعدش میزنیم که این هست:
python manage.py makemigrations
و این باعث میشه یک اصطلاحا snap shot از تغییرات دیتابیسیمون به زبان پایتونی ساخته بشه و برای هر app ای داخل migrations ذخیره بشه که بعدا وقتی میخوایم تغییرات رو واضحا روی دیتابیس اعمال کنیم، تغییرات و یا تعاریف جدید، ساخت table, field ازینجا خونده و اعمال میشه (در اصل به کد sql ای تبدیل میشه)
راجع به اولی __init__ که قبلا گفتیم، دومی یعنی apps برای کانفیگ کردن هر app جنگو استفاده میشه و هر app ای که بسازیم دقیقا همه این ماژول هارو داره.
با models و views هم که آشنا شدیم
اما admin چیه ؟ برای اینه که کنترل کنیم دیتا و اطلاعات با چه ظاهری و چجوری تو پنل ادمین نمایان بشه.
و آخری هم یعنی tests برای نوشتن تست های برنامه ما هستش.
خب اولین کاری باید بعد ساختن هر app جنگو بکنیم، این هستش که بریم توی settings.py پروژه و اسم app خودمون رو داخل INSTALLED_APPS اضافه کنیم.
این باعث میشه جنگو بفهمه این app ساخته شده و باید ازش استفاده کنه :)
حالا یه دید کلی داشته باشیم که اصلا میخوایم چیکار کنیم و روند کار چجوریه !
۱- یوزر به یک url ای میره
۲- یک http request از طرف یوزر به url فرستاده میشه
۳- این url باید به یک view function ای متصل شده باشه تا بتونه این request رو پاس بده به اون فانکشن خاص
۴- اون فانکشن خاص حالا request رو گرفته و میتونه ببینه چی هست اصلا
۵- معمولا اینجا view function ما باید یک صحبتی با database داشته باشه یعنی مدل ها
میاد یه کوئری میزنه به دیتابیس که مثلا لیست تمامی فیلم هارو بده به من
۶- در آخر هم با render کردن یک فایل html ای اطلاعات رو به کاربر نشون میده
خب پس الان ما نیاز داریم یک چیزی داشته باشیم که بتونیم فیلم هارو توش ذخیره کنیم، ازش بخونیم و ...
بریم یه مدل بسازیم به اسم Movie
we just keep it simple :)
تو ماژول models.py این کد رو مینویسیم:
یه entity ساختیم که در واقع تبدیل میشه به یک table توی دیتابیس نهایتا و سه تا field داره به اسم
name
که اسم فیلم هست، ۲۵۵ کاراکتر نهایتا میتونه باشه
publish_year
سال ساخت فیلم هست که میتونه ۴ رقم باشه نهایتا (۲۰۲۰)
has_watched
یه مقدار بولین میگیره که بصورت پیشفرض false هست که یعنی فیلم دیده نشده.
حالا باید یه مایگرشین بسازیم از تغییرات دیتابیسیمون
python manage.py makemigrations
حالا باید تغییرات رو اعمال کنیم تا واقعا این table توی دیتا بیس ساخته بشه + کلی table دیگه که خود جنگو اتوماتیک میسازه مثل table برای users و ...
python manage.py migrate
خب الان دیگه این تیبل ساخته شده تو دیتابیسمون :)
حالا نیاز داریم چندتا فیلم داشته باشیم که باهاش بتونیم کار کنیم، دیلیت کنیم یا ادیت کنیم یا اصلا نشونش بدیم و ...
تو ترمینال باید این کامند رو بزنیم تا به شل جنگو بریم
python manage.py shell
یه instance از Movie میسازیم و attribute هاش رو پر میکنیم به این شکل:
خودتونم مثل همین ۲-۳ تا دیگه آبجکت فیلم بسازید :)
اگه دقت کرده باشید وقتی میخوایم Object جدیدمون که firstmovie هست رو ببینیم فقط میگه Movie Object و یک عدد که ID اون آبجکت هست
برای اینکه بتونیم اسم فیلم رو ببینیم باید متد __str__ کلاس Movie رو override کنیم
خب دوباره باید پایتون شل ران کنیم تا ببینیم درست شده ؟
درست شده :)
حالا نیاز داریم یه url ای داشته باشیم که وقتی یورز میره اونجا یه view فانکشنی trigger بشه و همه فیلم هارو از دیتابیس بگیره و آماده کنه.
اول بیاید view رو بنویسیم :)
توضیحات:
یه فانکشن تعریف کردیم به اسم movie_list
یه متغیر داریم به اسم queryset که با جنگو ORM تمامی آبجکت های فیلم هارو گرفتیم
متغیری از جنس dictionary داریم به اسم context که مشخص کردیم movies کلیدی هست که value اون همون آبجکت فیلم ها هستش. ( ازین توی template استفاده میکنیم که جلوتر میبینیم)
نهایتا هم ریترن کردیم render رو با سه آرگومان یکیش request هست دومی فایل html ای که جلوتر میسازیمش
سومی هم همون دیکشنری ما که شامل فیلم ها هست تا بتونیم تو فایل html نشونشون بدیم.
حالا نیاز داریم url رو مشحص کنیم :)
اول از همه یک فایل به اسم urls.py باید بسازیم توی app جدیدمون یعنی movies
بعدش این کد بهش اضافه میشه:
توضیحات:
اسم اپ رو مشخص کردیم که عادت خوبیه ولی اجباری نیست!
متغیر urlpatterns در واقع برای خود جنگو هست و دقیقا ما طبق الگویی که باید ازش استفاده میکنیم
هر آیتم ازین لیست شامل یه فانکشن path هست با ۳ آرگومان
اولی route یا مسیر هست
دومی reference فانکشن view ما هست و آخری اسمی براش
حالا باید بریم تو urls.py پروژه اصلی یعنی movie_site
و بهش بگیم که هرکی به url ما رفت و به مسیر movies رسید، باید بقیه ش رو از urls.py اپ movies بپرسه ببینه باید چیکار کنه :)
اینجا فقط خط ۲۲ رو اضافه کردیم و include هم تو خط ۱۸ import کردیم :)
حالا باید template رو بسازیم
تو فولدر movies
یک فولدر جدید میسازیم به اسم templates
حالا توی فولدر templates یه فولدر جدید میسازیم به اسم app خودمون که اینجا movies هست و بعد توی این یه فایل میسازیم به اسم index.html
پس شد اینشکلی:
فایل index.html باید اینجوری باشه:
توضیحات: کار خاصی نکردیم همه ش تگ html ای هست
فقط با jinja که template engine دیفالت جنگو هست، یه لوپ زدیم و iterate کردیم روی آبجکت های فیلم که تو view فانکشن با متغیر context داده بودیمش به template و الان داریم تو اینجا ازش استفاده میکنیم :)
حالا بریم تست کنیم ببینیم درست کار میکنه یا چی :)
تو ترمینال باید اول وب سرور رو اجرا کنیم
python manage.py runserver
بصورت دیفالت وب سرور روی پورت ۸۰۰۰ اجرا میشه
ولی اگه میخواید عوضش کنید
python manage.py runserver 8001
حالا وب سرور بالا اومده
مرورگرتون رو باز کنید و برید به این آدرس
http://127.0.0.1:8000/movies/
باید این رو ببینید:
خب تبریک میگم الان اولین پروژه جنگویی خودتون رو نوشتید :)
بعدا میریم سراغ ORM جنگو
سوالی داشتید یا پیشنهادی، ممنون میشم کامنت کنید.
موفق باشید :)