یــــــعــــــنـــــی برنامه نویس =)))
ساخت یک Middleware سفارشی برای پروژه جنگو

سلام دوسِتان =))
در ابتدا بگم که من این پست رو به زبون انگلیسی هم در سایت مدیوم منتشر کردم اگر دلتون خواست میتونید از این لینک بخونید (اگر هم خواستید میتونید جفتشو بخونید، به خدا که من راضیم :دی )
ـMiddleware ها چی هستند؟
خیلی ساده بگم و گیجتون نکنم، Middleware ها در اصل کلاسهایی هستن که شامل یک یا چند تابع به خصوص هستند که قبل و بعد از تابعهای View فراخوانی میشوند. برای اطلاعات بیشتر راجع به چرایی و چگونگی طی شدن این فرایند میتونید این بلاگ پست رو مطالعه کنید
ـMiddleware ها چه نیازمندیهایی دارند؟
تنها نیازمندیای که یک کلاس داره تا به یک Middleware تبدیل بشه اینه که یکی از توابع زیر رو داشته باشه :
process_requestprocess_viewprocess_responseprocess_exception
البته که به دلیل تغییراتی که توی نسخههای جدید جنگو اعمال شده راه ساده برای نوشتن یک Middleware اینه که علاوه بر داشتن حداقل یکی از توابع فوق، کلاس ما از MiddlewareMixin نیز ارثبری کرده باشه. این کلاس توابع سازنده و ترتیب توابع فوق رو برامون آماده کرده و دیگه نیازی به اضافه کردن تابعی اضافه به کلاس خودمون نداریم.
ـMiddleware ها چگونه کار میکنند؟
هر پروژه جنگو در فایل settings.py یک لیست به نام MIDDLEWARES ( در نسخه های قدیمیتر MIDDLEWARES_CLASSES ) داره که حاوی آدرس تمام Middleware های سر راه ریکوئست/ریسپانس هست.
بعد از اینکه ریکوئست توسط فریمورک دریافت میشه WSGI Handler شروع به ساخت یک شئ HttpRequest میکنه و در این روند ریکوئست را به توابع process_request درون هر Middleware پاس میده. ( Middleware های درون لیست به ترتیب از بالا به پایین بررسی میشوند و اگر یک Middleware دارای process_request نبود هیچ اتفاقی نمیافته و WSGI Handler فقط از این کلاس چشمپوشی میکنه )
بعد از اینکه شئ مربوطه ساخته شد و از تمام Middleware ها گذشت نوبت به این میرسه که به تابع View تحویل داده بشه اما قبل از اون دوباره باید توابع process_view درون هر Middleware یه نگاهی بهش بندازن و در صورت تایید به view تحویل داده بشه =))
حواستون باشه که توابعprocess_requestوprocess_viewباید None را به عنوان خروجی بازگردانند. البته که میتوانند یک شئHttpRequestرو بازگرداند که در این صورت WSGI Handler به جای ادامه دادن روند فعلی خودش، به چرخهprocess_responseمیانبر میزنه و ریسپانس رو برمیگردونه =))
اگر یک تابع View با خطا برخورد کند WSGI Handler وارد چرخه process_exception میشه در غیر این صورت اگر یک شئ HttpResponse رو باز بگرداند وارد چرخه process_response خواهد شد.
بر خلافprocess_requestوprocess_viewتوابعprocess_responseوprocess_exceptionفقط میتوانند محتوای ریسپانس را تغییر دهند.
خب دیگه بریم یکم کد بزنیم
در ابتدا یک پروژه جنگو با file tree زیر آماده میکنیم :
├── mysite
│ ├── manage.py
│ └── mysite
│ ├── __init__.py
│ ├── settings.py
│ ├── urls.py
│ └── wsgi.py
└── myapp
│ ├── __init__.py
│ ├── admin.py
│ ├── apps.py
│ ├── models.py
│ ├── MyMiddleware.py
│ ├── tests.py
│ ├── urls.py
└ └── views.pyحالا دوتا تابع view به پروژه خودمون اضافه میکنیم یکی برای تست process_request و یکی برای تست process_view :
بعد از اون محتوای فایل mysite/urls.py به صورت زیر تغییر میدیم :
همچنین دوتا ویو ای که بالا ساختیم رو به myapp/urls.py مشابه زیر اضافه میکنیم :
حالا نوبت به نوشتن Middleware رسیده که محتوای اون رو داخل فایل MyMiddleware.py به شکل زیر قرار دادیم :
همانطور که مشاهده میکنید طبق محتوای فایل فوق، هر ریکوئست با متد GET اگر دارای پارامتر p باشه جواب “Hello World =)” رو تحویل میگیره و اگر ریکوئستی به تابع process_view_test ارسال شد و پارامتر p رو بین پارامترهای GET نداشت جواب “This method only work for this view =)” رو تحویل میگیره.
و در نهایت کافیه Middleware ای که ساختیم رو به لیست Middlewareها درون settings.py اضافه کنیم مانند زیر :
نوبت به تست کدمون رسیده =))
Test 0 : curl http://127.0.0.1:8000/myview/
Output : Hello There =)
Test 1 : curl http://127.0.0.1:8000/myview/?p=2
Output : Hello World=)
Test 2 : curl http://127.0.0.1:8000/process_view_test/
Output : This method only work for this view =)
Test 3 : curl http://127.0.0.1:8000/process_view_test/?p=1
Output : Hello World=)
تمامی محتوای کد در این ریپوزیتوری گیتهاب در دسترستون هست.
ممنونم از این که این پست رو مطالعه کردید
امیدوارم که براتون مفید باشه =))
لایک و کامنت فراموش نشه...
سوال یا نظری بود در خدمتم.
نوشته شده با ❤️ توسط کوچیکتون حمیدرضا شجراوی =)))
مطلبی دیگر در همین موضوع
چگونه از اعلان نوع داده در پایتون ۳.۶ استفاده کنیم؟
مطلبی دیگر در همین موضوع
docker swarm
افزایش بازدید بر اساس علاقهمندیهای شما
OrionMind