کتابخانهای محبوب در پایتون
جنگو (Django) یک چارچوب توسعه برنامههای کاربردی وبمحور قابل استفاده با پایتون است که امکان توسعه سریع وبسایتهای امن با قابلیت نگهداری بالا را ارائه میکند. جنگو به برنامهنویسان وب کمک میکند کدهای تمیز، کارآمد و قدرتمندی بنویسند. علاوه بر اینکه در فهرست محبوبترین چارچوبهای وب قرار دارد، یکی از پراستفادهترین فناوریهای توسعه وب است. چارچوب مذکور، توسط پلتفرمهای محبوبی مثل اینستاگرام، یوتیوب، گوگل و غیره مورد استفاده قرار گرفته است. جنگو به توسعهدهندگان اجازه میدهد با کدنویسی کمتر، برنامههای کاربردی را با سرعت بیشتری تولید کنند. علاوه بر این، رایگان و منبعباز است، توسط جامعه فعالی از توسعهدهندگان پشتیبانی میشود، مستندات عالی دارد و قابلیتهای کاربردی زیادی در اختیار توسعهدهندگان قرار میدهد.
جنگو چگونه پدید آمد؟
جنگو اولین بار در سال 2003 میلادی، توسط آدریان هولواتی (Adrian Holovaty) و سایمون ویلیسون (Simon Willison) توسعه پیدا کرد و نشان داد که توانایی مدیریت سایتهای با ترافیک بالا را دارد. در طول این سالها نسخههای مختلفی از این چارچوب منتشر شده که جدیدترین نگارش آن نسخه 4.0 است که در سال 2022 میلادی منتشر شد. امروزه، جنگو یک پروژه متنباز مشارکتی است که طیف گستردهای از توسعهدهندگان در سراسر جهان در توسعه و رفع اشکالات آن مشارکت فعال دارند. بهطور کلی، جنگو به دلایل زیر پدید آمده است:
- طراحی تمیز: کدهای جنگو خوانایی زیادی دارند، زیرا جنگو توسعهدهندگان را تشویق میکند از قواعد استاندارد توسعه برنامههای کاربردی پیروی کنند.
- کدنویسی مختصر: کدنویسی کمتر به توسعهدهندگانی که بر مبنای متدولوژی توسعه سریع کار میکنند، اجازه میدهد در کمترین زمان ممکن یک نمونه اولیه تولید کنند.
- عدم تکرار: جنگو به توسعهدهندگان پیشنهاد میدهد هر یک از ماژولهای برنامه را بهجای اینکه در بخشهای مختلف برنامه کاربردی تکرار کنند، تنها در یک بخش بنویسند و به دفعات از آن استفاده کنند (قابلیت استفاده مجدد).
- توسعه سریع: جنگو به توسعهدهندگان اجازه میدهد در کوتاهترین زمان ممکن، برنامههای کاربردی را توسعه دهند.
- استقلال نسبی مولفههای مختلف: جنگو به گونهای توسعه پیدا کرده تا هر کدام از عناصر و مولفههای این چارچوب، تقریبا مستقل از یکدیگر باشند. البته در برخی موارد، وابستگیهایی وجود دارد.
آشنایی کلی با معماری جنگو
جنگو پلتفرمی برای توسعه برنامههای کاربردی وبمحور با استفاده از زبان پایتون است و از معماری MVC و MVT پشتیبانی میکند. هنگامیکه در مورد برنامههای کاربردی که واسط کاربری دارند صحبت میکنیم، در واقع اشاره به معماری خاصی داریم که معماری «مدل-نمایش-کنترلگر» (MVC) نام دارد. همانگونه که از نام معماری مذکور مشخص است، معماری MVC از سه مولفه مدل (Model)، نمایش (View) و کنترلگر (Controller) تشکیل شده است. معماری MVT، کمی متفاوتتر از معماری MVC است. تفاوت اصلی دو معماری فوق این است که در مدل MVT، کتابخانه جنگو مدیریت مؤلفه کنترلگر را بر عهده دارد. مؤلفه کنترلگر، کد نرمافزاری است که تعامل میان مولفههای مدل و نمایش را کنترل میکند.
با توجه به اینکه، در معماری MVT، کتابخانه جنگو مدیریت مولفه کنترلگر را برعهده میگیرد، بر عملکرد مولفه Template نیز نظارت میکند. مولفه Template یک فایل HTML است که با زبان قالب جنگو (Django Template Language) ترکیب میشود. شکل ۱، نحوه تعامل مولفههای مختلف معماری MVT با یکدیگر، جهت سرویسدهی به درخواست کاربر را نشان میدهد. بر مبنای معماری مذکور، توسعهدهنده، ماژول Model را تعریف میکند، سپس، با استفاده از View و Template مدل تعریفشده به یک آدرس اینترنتی نگاشت میشود و در نهایت، پلتفرم جنگو، محتوا یا سرویس مورد نظر را در اختیار کاربر قرار میدهد.
شکل 1
چرا توسعهدهندگان از جنگو استفاده میکنند؟
جنگو قابلیتهای زیر را در اختیار توسعهدهندگان قرار میدهد:
- قابلیتهای کاربردی گسترده: همانگونه که اشاره شد، جنگو ماژولها و توابع مختلفی در اختیار توسعهدهندگان قرار میدهد تا بتوانند کارها را به سادهترین شکل انجام دهند. جنگو قابلیتهای کاربردی را بهشکل یکپارچه ارائه میکند و از خطمشیهای کدنویسی استاندارد پشتیبانی میکند. علاوه بر این، مستندات بهروز و کاملی دارد.
- منعطف است: جنگو را میتوان برای ساخت هر نوع وبسایتی از سیستمهای مدیریت محتوا و ویکیها گرفته تا شبکههای اجتماعی و سایتهای خبری مورد استفاده قرار داد. رویکرد فوق میتواند با هر چارچوب سمت کاربر کار کند و میتواند محتوا را تقریبا در هر قالبی (از جمله HTML، فیدهای RSS ،JSON ،XML و غیره) ارائه دهد.
- ایمن است: جنگو مانع از آن میشود تا توسعهدهندگان اشتباهات رایج امنیتی که ممکن است وبسایت را با خطر جدی روبهرو کنند، مرتکب شوند. به همین دلیل در مقایسه با چارچوبهایی مثل لاراول زبان برنامهنویسی پیاچپی کدهای آن از منظر امنیتی کیفیت بهتری دارند. بهعنوان مثال، جنگو روشی امن برای مدیریت حسابهای کاربری و رمزهای عبور ارائه میکند، از اشتباهات رایج مانند قرار دادن اطلاعات نشست در کوکیهایی که آسیبپذیر هستند یا ذخیرهسازی مستقیم رمزهای عبور اجتناب میکند و از مکانیزم هش برای محافظت از رمزهای عبور استفاده میکند. در جنگو کوکیها تنها شامل یک کلید هستند و دادههای واقعی در پایگاه داده ذخیره میشوند.
هش رمز عبور یک مقدار با طول ثابت است که رمز عبور را با استفاده از تابع هش رمزگذاری میکند. هنگامی که رمزعبوری، رمزگذاری میشود در ادامه از تابع هش برای مقایسه خروجی هش رمزعبور با مقدار اصلی استفاده میشود تا صحت رمز عبور تایید شود. با توجه به ماهیت یک طرفه تابع، اگر مقدار هش ذخیرهشده دستکاری شود، جنگو بهسرعت از این موضوع مطلع میشود و مانع از آن میشود تا هکرها بهسادگی به رمزهای عبور دسترسی داشته باشند.
یکی از مزایای بزرگ جنگو محافظت از برنامههای کاربردی وبمحور در ارتباط با آسیبپذیریهایی مثل تزریق کد اسکیوال، اسکریپتهای بین سایتی، جعل درخواست بین سایتی و روبایش کلیک است.
- مقیاسپذیر است: جنگو از یک معماری مولفهگرای خاص که «عدم-اشتراکگذاری» نام دارد استفاده میکند، بهطوری که هر بخش از معماری مستقل از بخشها است و از اینرو میتوان آنرا جایگزین یا در صورت نیاز تغییر داد. این مکانیزم تفکیک صریح بخشهای مختلف به این معنا است که هنگامی که ترافیک افزایش پیدا میکند، میتوان سختافزارهایی مثل سرورهای کش، سرورهای پایگاه داده یا سرورهای برنامه را به سادهترین شکل به زیرساخت اضافه کرد. به همین دلیل است که وبسایتهای با ترافیک سنگین مثل اینستاگرام از این چارچوب استفاده میکنند.
- قابل نگهداری است: کد جنگو با استفاده از اصول و الگوهای طراحی نوشته شدهاند که توسعهدهندگان را به نوشتن کدهای قابل نگهداری و قابل استفاده مجدد تشویق میکند. این چارچوب از اصل «خودت را تکرار نکن» (Don’t Repeat Yourself) به بهترین شکل پشتیبانی میکند تا کدهای تکراری نوشته نشود و حجم کدها کم شود. علاوه بر این، از گروهبندی عملکردهای مرتبط با هدف قابلیت استفاده مجدد و گروهبندی کدهای مرتبط در ماژولهای همسو با معماری MVC پشتیبانی میکند.
- قابل حمل است: جنگو به زبان پایتون نوشته شده که قابلیت اجرا روی پلتفرمهای مختلف را دارد. به بیان دقیقتر، شما به هیچ پلتفرم سرور خاصی وابسته نیستید و میتوانید برنامههای خود را روی لینوکس، ویندوز و macOS اجرا کنید. علاوه بر این، جنگو توسط بیشتر ارائهدهندگان خدمات میزبانی وب پشتیبانی میشود.
کدهای جنگو چه شکلی دارند؟
در یک وبسایت سنتی دادهمحور، یک برنامه وب صبر میکند تا درخواستهای HTTP از مرورگر وب کاربر دریافت شود. هنگامیکه درخواستی دریافت میشود، برنامه بر اساس آدرس اینترنتی و اطلاعات موجود در دادههای POST یا GET ملزومات مورد نیاز را بررسی میکند. بسته به آنچه مورد نیاز است ممکن است اطلاعات از یک پایگاه داده خوانده یا در آن نوشته شوند. سپس، برنامه پاسخی را برای مرورگر وب ارسال میکند و اغلب بهصورت پویا یک صفحه HTML را برای مرورگر ایجاد و ارسال میکند تا مرورگر بتواند دادههای دریافتی را بهشکل درستی در قالب HTML نمایش دهد. بهطور معمول، برنامههای وبمحور جنگو کدهای موردنیاز برای انجام مراحل مذکور را در فایلهای جداگانهای قرار میدهند (شکل 2). مولفههای نشاندادهشده در شکل ۲ بهشرح زیر هستند:
شکل 2
- URLها: در حالی که پردازش درخواستها از هر آدرس اینترنتی از طریق یک تابع واحد امکانپذیر است، نوشتن یک تابع نمایش جداگانه برای مدیریت هر منبع فرآیند نگهداری از کدها را سادهتر میکند. در اینجا، یک نگاشتکننده آدرس اینترنتی برای هدایت درخواستهای HTTP به مولفه نمایش مناسب بر اساس آدرس اینترنتی درخواستشده استفاده میشود. نگاشتکننده آدرس اینترنتی میتواند الگوهای خاصی از رشتهها یا ارقام را که در آدرس اینترنتی ظاهر میشوند تطبیق داده و آنها را بهعنوان داده به یک تابع نمایش ارسال کند.
- View: یک تابع کنترلکننده درخواست است که درخواستهای HTTP را دریافت میکند و پاسخهای HTTP را برمیگرداند. نمایشها (Views) به دادههای مورد نیاز برای پاسخگویی به درخواستها از طریق مدلها دسترسی دارند و فرآیند قالببندی پاسخ را به الگوها واگذار میکنند.
- Models: اشیاء پایتون هستند که ساختار دادههای یک برنامه کاربردی را تعریف میکنند و مکانیسمهایی را برای مدیریت (افزودن، اصلاح، حذف) و پرسوجو رکوردها در پایگاه داده ارائه میکنند.
- Templates: الگو یا قالب یک فایل متنی است که ساختار یا طرحبندی یک فایل (مانند صفحه HTML) را با متغیرهایی که برای نمایش محتوای واقعی استفاده میشود، تعریف میکند. یک view میتواند بهصورت پویا یک صفحه HTML را با استفاده از یک الگوی HTML ایجاد کند و دادههای موردنیاز یک مدل را در اختیارش قرار دهد. یک الگو میتواند برای تعریف ساختار هر نوع فایلی استفاده شود و ضرورتی ندارد تا حتما HTML باشد.
همانگونه که ابتدای مقاله به آن اشاره کردیم، جنگو از MVT و MVC پشتیبانی میکند که الگوی بالا مبتنی بر معماری MVT است.
ارسال درخواست به تابع نمایش صحیح (urls.py)
بهطور معمول، یک نگاشتکننده آدرس اینترنتی در فایلی بهنام urls.py ذخیره میشود. در قطعه کد زیر، نگاشتکننده (urlpatterns) فهرستی از نگاشتهای بین مسیرها (الگوهای آدرس اینترنتی خاص) و توابع نمایش مربوطه را تعریف میکند. اگر یک درخواست HTTP دریافت شود که دارای آدرس اینترنتی منطبق با الگوی مشخصشده باشد، تابع نمایش مربوطه فراخوانی میشود و درخواست ارسال میشود. قطعه کد زیر این موضوع را نشان میدهد.
urlpatterns = [
path(‘admin/’, admin.site.urls),
path(‘book/<int:id>/’, views.book_detail, name=’book_detail’),
path(‘catalog/’, include(‘catalog.urls’)),
re_path(r’^([0-9]+)/$’, views.best),
]
رسیدگی و مدیریت درخواست (views.py)
مولفه نمایش (View) قلب برنامههای وب است، درخواستهای HTTP را از کلاینتهای وب دریافت میکند و پاسخهای HTTP را برمیگرداند. برای این منظور مولفههای نمایش به پایگاههای دادهای، الگوهای پردازش و غیره دسترسی دارند. قطعه کد زیر، یک تابع نمایش را که index نام دارد نشان میدهد که میتواند توسط مولفه نگاشتکننده آدرس اینترنتی قطعه کد قبل فراخوانی شود. قطعه کد زیر، یک شیء HttpRequest را بهعنوان پارامتر (درخواست) دریافت میکند و یک شیء HttpResponse را برمیگرداند. در این مورد، ما هیچ کاری با درخواست انجام نمیدهیم و تنها پاسخ را در قالب رشته دریافت میکنیم.
# filename: views.py (Django view functions)
from django.http import HttpResponse
def index(request):
# Get an HttpRequest - the request parameter
# perform operations using information from the request.
# Return HttpResponse
return HttpResponse(‘Hello from Django!’)
Viewها در فایلی که views.py نامیده میشود ذخیره میشوند.
تعریف مدلهای داده (models.py)
برنامههای تحت وب مبتنی بر جنگو، دادهها را از طریق اشیاء پایتون که به آنها «مدل» میگویند مدیریت کرده و محاورههایی روی آنها انجام میدهند. مدلها ساختار دادههای ذخیرهشده مثل انواع فیلدها و حداکثر اندازه، مقادیر پیشفرض، گزینههای فهرست انتخاب، متن راهنما برای مستندات، متن برچسب برای فرمها، و غیره را تعریف میکنند. تعریف مدل، مستقل از پایگاه داده زیربنایی است. قطعه کد زیر یک مدل جنگو بسیار ساده برای یک شیء Team را نشان میدهد. کلاس Team از کلاس models.Model اقتباس شده است. در قطعه کد زیر، نام تیم و سطح تیم بهعنوان فیلدهای کاراکتری تعریف شدهاند. همچنین، حداکثر تعداد کاراکترهایی که برای هر رکورد ذخیره میشود تعیین شده است. team_level میتواند یکی از چند مقدار باشد؛ از اینرو، ما آنرا بهعنوان یک فیلد انتخابی تعریف میکنیم و نگاشتی میان گزینههای نمایشدادهشده و دادههای ذخیرهشده بههمراه یک مقدار پیشفرض ارائه میدهیم.
# filename: models.py
from django.db import models
class Team(models.Model):
team_name = models.CharField(max_length=40)
TEAM_LEVELS = (
(‘U09’, ‘Under 09s’),
(‘U10’, ‘Under 10s’),
(‘U11’, ‘Under 11s’),
... #list other team levels
)
team_level = models.CharField(max_length=3, choices=TEAM_LEVELS, default=’U11’)
اجرای کوئریها روی دادهها (views.py)
مدل جنگو یک واسط برنامهنویسی کاربردی برای اجرای پرسوجوهای ساده روی پایگاه داده در اختیار برنامهنویسان قرار میدهد. واسط فوق میتواند با تعدادی از فیلدها در یک زمان با استفاده از معیارهای مختلف اجرا شود و میتواند از عبارات پیچیده پشتیبانی کند. قطعه کد زیر یک تابع نمایش (کنترلر منابع) را برای نمایش همه تیمهای U09 نشان میدهد.
خط list_teams = Team.objects.filter(team_level__exact=”U09”) نشان میدهد که چگونه میتوانیم از API query مدل برای فیلتر کردن همه رکوردهایی استفاده کنیم که در آنها فیلد team_level دقیقا مقدار «U09» را دارد (توجه داشته باشید که چگونه این معیار بهعنوان فیلتر برای آرگومان عمل میکند).
## filename: views.py
from django.shortcuts import render
from .models import Team
def index(request):
list_teams = Team.objects.filter(team_level__exact=”U09”)
context = {‘youngest_teams’: list_teams}
return render(request, ‘/best/index.html’, context)
قطعه کد بالا از تابع render برای ساخت HttpResponse که برای مرورگر ارسال میشود استفاده میکند و نقش یک میانبر را دارد. قطعه کد بالا یک فایل HTML با ترکیب یک الگوی HTML مشخص و برخی دادهها که در قالب (در متغیری به نام context ارائه شده است) افزوده میشوند، ایجاد میکند.
پردازش دادهها (الگوهای HTML)
قالبها این امکان را میدهند تا ساختار یک سند خروجی را که قرار است دادهها در آن قرار بگیرند مشخص کنید. قالبها اغلب برای ساخت HTML استفاده میشوند، اما میتوانند انواع دیگری از اسناد را ایجاد کنند. جنگو هم از سیستم قالب بومی خود و هم از یک کتابخانه محبوب پایتون به نام Jinja2 پشتیبانی میکند. قطعه کد زیر نشان میدهد که الگوی HTML فراخوانیشده توسط تابع render در بخش قبل ممکن است چه شکلی باشد. الگوی مذکور با این فرض نوشته شده که وقتی پردازش میشود به یک متغیر لیست که Youngest_teams نام دارد دسترسی خواهد داشت. در بدنه HTML دستوری داریم که بررسی میکند آیا متغیر Youngest_teams وجود دارد یا خیر و سپس از طریق یک حلقه for محتوای آنرا میخواند. در هر تکرار، الگو مقدار team_name را از طریق عنصر <li> نشان میدهد.
## filename: best/templates/best/index.html
<!DOCTYPE html>
<html lang=”en”>
<head>
<meta charset=”utf-8”>
<title>Home page</title>
</head>
<body>
{% if youngest_teams %}
<ul>
{% for team in youngest_teams %}
<li>{{ team.team_name }}</li>
{% endfor %}
</ul>
{% else %}
<p>No teams are available.</p>
{% endif %}
</body>
</html>