محمد حسن خدامی
محمد حسن خدامی
خواندن ۵ دقیقه·۴ ماه پیش

ارور 405 در جنگو


سلام امروز با یه آموزش اینجام!

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

لیست HTTP Status Coide

خب یه Status code که در مقاله ی بالا بهش اشاره نکردم 405 هست! خب قضیه 405 چیه ؟ و چرا الان دارم براش یه مقاله جداگونه مینویسم و به نظرم خیلی مهمه ؟ چون درست هندل نکردن این ارور میتونه منجر به یک فاجعه ی بزرگ توی سایت بشه ... چرا؟

  • 1- تجربه کاربری ضعیف
  • 2- عدم اطلاع رسانی مناسب
  • 3- مشکلات SEO
  • 4- احتمال لو رفتن اطلاعات سرور

خب حالا بیایم از پایه بررسی کنیم ببینیم چطور این ارور به وجود میاد

بازم باید یه فلش بک بزنم به مقاله های قبلیم یادتونه راجب GET و POST اومده بودم یه مقاله نوشته بودم. پیشنهاد میکنم که بخونید

دستور GET در برابر دستور POST

بیاید براتون یه مثال از دنیای واقعی بزنم اول:

فرض کنید که یه مغازه داریم و ما فروشنده هستیم یه آقایی توی این مغازه ما کار میکنه به نام حسن آقا!

این آقا کارش این هست که میاد و محصول رو برای مشتری توی کیسه پلاستیک میذاره، هیچکس این حسن آقا گل گلاب رو نباید ببینه! چون قیافه ترسناکی داره و ممکنه مشتری ما بترسه و دیگه هیچ وقت پاشو توی مغازه ی ما نذاره!

خب حالا بریم توی سایت و جنگو

ما یه فروشگاه داریم که یک View داریم که کارش اضافه کردن محصولات به سبد خرید هست و هیچ کار دیگه ای نمی کنه. سبد خرید ما 2 شاخصه مهم داره

  • تعداد
  • محصول

پس درخواست بایستی به صورت POST ارسال بشه. چرا ؟ چون هر محصول یک Form داره که ما در اون تعداد رو مشخص میکنیم. کدی که نوشته شده رو خوب بررسی کنید لطفا :)

بخوام یه توضیح کوتاه بدم method Post این کلاس میاد از ما آیدی محصول رو میگیره ، میره چک میکنه ببینه توی انبار موجود هست یا نه بعدش یه فرم نشون میده میگه چند تا میخوای و ما بهش میگیم چند تا میخوایم و بعدش میاد به سبد خرید ما اضافه اش میکنه. (دقیقا مثل حسن آقا که مثال زدم، فقط هیچکس نباید ببینه حسن آقا رو!)
بخوام یه توضیح کوتاه بدم method Post این کلاس میاد از ما آیدی محصول رو میگیره ، میره چک میکنه ببینه توی انبار موجود هست یا نه بعدش یه فرم نشون میده میگه چند تا میخوای و ما بهش میگیم چند تا میخوایم و بعدش میاد به سبد خرید ما اضافه اش میکنه. (دقیقا مثل حسن آقا که مثال زدم، فقط هیچکس نباید ببینه حسن آقا رو!)


همه ی View ها یک url دارن! و این view با دستور post کار میکنه. حالا اگر یک فردی بیاد و url این view رو سرچ کنه چه اتفاقی میفته ؟!

آفرین ! حسن آقا رو میبینه!!!!!

این قیافه حسن آقاست ! یا همون ارور 405 ما :)))))))))))
این قیافه حسن آقاست ! یا همون ارور 405 ما :)))))))))))

اگرم تا الان بهم گفتید بی مزه با تمام احترام بی مزه خودتونید :))))))))))))

یکم تخصصی تر حرف بزنم ! هیچ مشتری دوست نداره ارور ببینه وقتی که میخاد خریدی رو انجام بده یا هیچ کارفرمایی دوست نداره وقتی داره یکی از url هاشو تست میکنه همچین صفحه ی زشتی و کریهی رو ببینه


چرا این اتفاق افتاد؟

به زبان فارسی ساده : ما یه view داریم که فقط request باید به صورت POST برای اون ارسال بشه اما کاربر اومده و با GET این درخواست رو ارسال کرده.


راه حل چیه ؟

راه حل ما به چند مرحله تقسیم میشه. پس بیاید بهتون بگم

1- اول برای تمیز تر شدن کد و اینکه خیالمون راحت بشه یه وقت باگ نخوره کد میایم و به کلاسمون method GET رو اضافه میکنیم اما به صورت زیر

3 خط اول رو نگاه کنید. Method POST رو هیچ دستی بهش نزدیم اما اومدیم یه Method GET اضافه کردیم
3 خط اول رو نگاه کنید. Method POST رو هیچ دستی بهش نزدیم اما اومدیم یه Method GET اضافه کردیم

داخل این METHOD GET اومدیم گفتیم که آقا جان فقط و فقط method POST مجازه دیگه هیچ چیزی جز اون مجاز نیست!

فقط یادتون نره که HttpResponseNotAllowed رو ایمپورت کنید!

from django.http import HttpResponseNotAllowed

یه نگاهی به Django Document بندازیم



class HttpResponseNotAllowed

Like HttpResponse, but uses a 405 status code. The first argument to the constructor is required: a list of permitted methods (e.g. ['GET', 'POST']).



خیلی ساده بخوام ترجمه اش کنم گفته مثل HttpResponse هست اما از کد 405 استفاده میکنه و باید حتما یک آرگومان براش بفرستید که باید یک لیستی از method های مجاز باشه.

همونکاری که ما توی کدمون کردیم ! بهش گفتیم فقط Method POST مجاز هست نه چیز دیگه ای!

خب این مرحله اول بود بریم سراغ مرحله دوم

2- ساخت صفحه ی html ارور 405 !

به این صورت در کنار base.html میام و  با اسم کد ارور صفحه ی html خودم رو میسازم
به این صورت در کنار base.html میام و با اسم کد ارور صفحه ی html خودم رو میسازم


و داخلش کد های زیر رو نوشتم ، حالا سلیقه ای هست شما هرجور دوست دارید بنویسید!

من به عنوان یک Backend کار بی سلیقه ! سلیقه ام اینه :)))) چقدر سلیقه تکرار شد :))))
من به عنوان یک Backend کار بی سلیقه ! سلیقه ام اینه :)))) چقدر سلیقه تکرار شد :))))


ما با این کارمون یجورایی حسن آقا رو فرستادیم جراحی پلاستیک!!

اما هنوز کارمون 2 تا ایراد کوچولو داره وقتی دوباره به url میریم که ارور 405 میخوریم باز عکس حسن آقا قبل از جراحی پلاستیک رو نشون میده!! علتش چیه ؟

1- چون که ما هنوز روی Development هستیم ! و Debug = True هست ! ما برای تست صفحه های ارور بایستی بریم روی حال Production.

پس میریم داخل settings.py و تنظیمات زیر رو انجام میدیم

Debug = False
AllowedHost = ['127.0.0.1']


2- مشکل دوم! متاسفانه یه حقیقت تلخی که وجود داره این هست که جنگو برای ارور 405 هندلر خاصی نداره :)) (من هرچی سرچ کردم نبود! اگر شما بلدید حتما به منم یاد بدید!) بنابراین باید بیایم خودمون override اش کنیم.

خب یادتونه توی view اومدیم و method GET نوشتیم ؟ حالا باید تغییر اش بدیم!

بذارید توضیح بدم دقیقا چیکار میکنیم!

اول میایم و تابع render رو صدا میزنیم و میگیم رو request و اون صفحه ی Html رو دریافت کن، اما مثل همیشه Return اش نمی کنیم! و داخل یک متغیر ذخیره اش میکنیم.

و بعدش در خط بعد با HttpResponseNotAllowed میایم و اون رو هم Return میکنیم!

یکم توضیحش سخت شد میدونم! اگر متوجه نشدید سوال بپرسید.

و نتیجه به همین زیبایی هست که میبینید ! حسن آقا بعد از جراحی پلاستیک !  راستی اینکه می بینید اعداد رو فارسی نشون میده بخاطر یه package هست که خودم نوشتمش ! البته توی نت 10000 تا مثل اش موجوده ولی توی گیت هاب میذارم این پکیج رو بزودی !
و نتیجه به همین زیبایی هست که میبینید ! حسن آقا بعد از جراحی پلاستیک ! راستی اینکه می بینید اعداد رو فارسی نشون میده بخاطر یه package هست که خودم نوشتمش ! البته توی نت 10000 تا مثل اش موجوده ولی توی گیت هاب میذارم این پکیج رو بزودی !


یه نکته مهم وجود داره که در مواقع خیلی کمی ما نیاز به هندل کردن ارور 405 داریم . (اگر پروژه ای دارید که خیلی زیاد توش این اتفاق می افته میتونیم براش mixin بسازیم.)

راستی آدرس GitHub من :

گیت هاب من

خب همین دیگه! موفق باشید :))))




برنامه نویسیجنگوگیت هابپایتون
نوشته ها و آموزش های یک برنامه نویس که بنظر خودش خسته هست اما به نظر دیگران خستگی نمیشناسه. بیشترم راجب پایتون و جنگو نظر میده ! سایت شخصیشم فعلا Down شده چون پول هاستشو نداده!
شاید از این پست‌ها خوشتان بیاید