ادامه آموزش فریم ورک جنگو – View ها و UrlConf ها

ادامه آموزش فریم ورک جنگو – View ها و UrlConf ها

0 تومان
کد محصول: View ها و UrlConf ها
وضعیت انبار: در انبار

مشخصات کوتاه محصول

آموزش فریم ورک جنگو - مقدمه  آموزش فریم ورک جنگو – فرم هاآموزش فریم ورک جنگو – Session ها ، کاربران و عضویتآموزش فریم ورک جنگو – شروع کارآموزش فریم ور...

آموزش فریم ورک جنگو - مقدمه  

آموزش فریم ورک جنگو – فرم هاآموزش فریم ورک جنگو – Session ها ، کاربران و عضویت

آموزش فریم ورک جنگو – شروع کار

آموزش فریم ورک جنگو –  View ها و UrlConf های پیشرفته آموزش فریم ورک جنگو – مبحث Caching  

آموزش فریم ورک جنگو – View ها و UrlConf ها    

آموزش فریم ورک جنگو – Template های پیشرفته  آموزش فریم ورک جنگو – پکیج Django.contrib

آموزش فریم ورک جنگو – Template ها  

آموزش فریم ورک جنگو – مدل های پیشرفتهآموزش فریم ورک جنگو – مبحث Middleware

آموزش فریم ورک جنگو – مدل ها 

آموزش فریم ورک جنگو – Viewهای Generic  آموزش فریم ورک جنگو – یکپارچه سازی برنامه ها و دیتابیس Legacy  

آموزش فریم ورک جنگو – سایت مدیر 

آموزش فریم ورک جنگو – تولید محتوای غیر Html ی    آموزش فریم ورک جنگو – بین المللی سازی   


آموزش فریم ورک جنگو – امنیت


 ادامه مبحث آموزش فریم ورک جنگو – View ها و UrlConf ها

 

در بخش قبل از آموزش فریم ورک جنگو – View ها و UrlConf ها تا بررسی کد زیر رسیدیم و از اینجا به بعد ادامه کار را دنبال خواهیم کرد.در صورتیکه بخش اول آموزش فریم ورک جنگو – View ها و UrlConf ها را مطالعه نکردید حتما قبل از اینکه بخش دوم را ادامه دهید از اینجا وارد بخش اول شده و آن را مطالعه نمائید چرا که لازمه ی این بخش است.

خب در بخش قبلی تا اینجای کار رسیدیم که  تابع hello نیز باید درون views.py وجود داشته باشد، ما تابع hello را در این کد فوق برای اختصار حذف کردیم. در اینجا view کامل را مشاهده می کنید.

from django.http import HttpResponse
import datetime

def hello(request):
    return HttpResponse("Hello world")

def current_datetime(request):
    now = datetime.datetime.now()
    html = "<html><body>It is now %s.</body></html>" % now
    return HttpResponse(html)

  بررسی کد فوق:

  • در ابتدا برای محاسبه تاریخ و زمان، ماژول datetime را به بالای views.py اضافه کردیم.
  • تابع جدید current_datetime زمان و تاریخ جاری را محاسبه می کند، و آنرا به صورت شیء درون متغیر محلی now ذخیره می کند.
  • دومین خط از کد داخل تابع view یک پاسخ (request) HTML با استفاده از قابلیت format-string پایتون ایجاد می کند. %s داخل رشته بدین معناست که مقدار متغیر now جایگزین %s خواهد شد. متغیر now رشته نیست بلکه یک شیء datetime.datetime می باشد، ولی %s آن را به رشته تبدیل می کند، که چیزی شبیه به "14:09:39.002731 13-12-2008" می باشد.
  • در پایان، تابع view همانند تابع hello یک شیء HttpResponse که حاوی پاسخ تولید شده است بر می گرداند.

بعد از اضافه کردن تابع جدید به views.py، یک URLpattern نیز داخل urls.py ایجاد می کنیم، که برای جنگو مشخص شود که کدام URL باید view مورد نظر خود را کنترل کند.

from django.conf.urls.defaults import *
from mysite.views import hello, current_datetime

urlpatterns = patterns('',
    ('^hello/$', hello),
    ('^time/$', current_datetime),
)

دو تغییر ایجاد شده است. اول اینکه تابع current-datetime را در بالا import کردیم. و دومین تغییر که مهم تر از تغییر اول می باشد، یک URLpattern با آدرس /tim/ برای view جدید اضافه کرده ایم. آیا قلق کار دستتان آمد؟

با نوشتن view جدید و تغییر دادن URLconf سرور را اجرا کرده و درون مرورگر به این آدرس بروید http://127.0.0.1:8000/time/. شما باید زمان جاری را در صفحه مورد نظر مشاهده کنید.

منطقه زمانی جنگو

بسته به رایانه شما، زمان و تاریخ ممکن است چند ساعتی متفاوت باشد. دلیل این است که جنگو دارای منطقه زمانی می باشد و تنظیم پیشفرض آن بر روی America/Chicago می باشد. (این زمان برای جایی است که توسعه دهندگان اصلی در آنجا زندگی می کنند) اگر شما در جای دیگری زندگی می کنید می توانید این پیشفرض را تغییر دهید. برای این تنظیم کامنتی وجود دارد که می توانید در آن لینک مربوط برای به روز رسانی لیست جهانی منطقه زمانی را پیدا کنید.

URLconf و مفهوم Loose Coupling

حالا زمان خوبی است برای پرداختن به فلسفه کلیدی پشت URLconfs و جنگو: قانون loose coupling. به عبارت ساده، loose coupling یک شیوه توسعه نرم افزار است که در ساختن بخش های قابل تعویض اهمیت دارد. اگر دو بخش از کد به صورت loosely couple پیاده سازی شده باشند، هنگامی که در یک بخش تغییری ایجاد می کنیم، بر روی بخش دیگر تاثیر نمی گذارد و یا تاثیر بسیار کمی دارد.

URLconf جنگو یک مثال بسیار خوب از این قانون می باشد. در یک برنامه وب جنگو تعریف های URL و توابع view، به صورت loosely couple نامیده می شوند؛ برای مثال، به تابع current_datetime ملاحظه کنید. اگر بخواهیم URL مربوط یه این تابع view را از /time/ به /current-time/ تغییر دهیم، می توانیم به سرعت و بدون هیچ نگرانی نسبت به تابع view مربوط به آن در URLconf تغییر ایجاد کنیم. به همین صورت اگر بخواهیم تابع view را نیز تغییر دهیم می توانیم بدون تاثیر بر روی URL آن این تابع را تغییر دهیم.

بعلاوه اگر بخواهیم تابع current-date را برای چندین URL نمایش دهیم، می توانیم خیلی آسان URLconf را بدون هیچ گونه لمسی در تابع view تغییر دهیم. در مثال که در زیر مشاهده خواهید کرد، current-datetime برای دو URL در دسترس خواهد بود.

urlpatterns = patterns('',
    ('^hello/$', hello),
    ('^time/$', current_datetime),
    ('^another-time-page/$', current_datetime),
)

URLconf ها و view ها در عمل به صورت loosely couple پیاده سازی شده اند. ما در سرتاسر این کتاب از طریق مثال ها به این فلسفه مهم (loosely coupling) اشاره خواهیم کرد

سومین view: آدرس های پویا (dynamic)

در تابع current_datetime، محتویات صفحه یعنی زمان و تاریخ نشان داده شده، داینامیک بوده، اما URl (/time/) استاتیک می باشد. در اغلب برنامه های داینامیک وب، یک URL حاوی پارامترهایی است که بر روی خروجی صفحه تاثیر می گذارد. برای مثال یک فروشگاه کتاب آنلاین ممکن است برای هر کتاب URL مخصوص به خود را داشته باشد، مانند /books/243/ و /book/81196/.

بیایید view سوم خودمان را با حالت URL داینامیک ایجاد کنیم که درون URL ساعت را دریافت کند. هدف از ساختن این سایت این است که در صورت وارد کردن /time/plus/1/ خروجی یعنی همان زمان و تاریخ در یک ساعت جلوتر نشان دهد، صفحه /time/plus/2/ زمان را 2 ساعت جلوتر از زمان فعلی نشان دهد، صفحه /time/plus/3/ زمان را 3 ساعت جلوتر نشان دهد و الی آخر.

یک تازه کار یا مبتدی ممکن است فکر کند برای هر ساعت یک تابع view مجزا لازم است:

urlpatterns = patterns('',
    ('^time/$', current_datetime),
    ('^time/plus/1/$', one_hour_ahead),
    ('^time/plus/2/$', two_hours_ahead),
    ('^time/plus/3/$', three_hours_ahead),
    ('^time/plus/4/$', four_hours_ahead),
)

کد فوق به وضوح مشخص است که ناقص می باشد. نه تنها توابع view اضافه و زائد می باشند، بلکه برنامه اساسا به طور محدود تنها از 4 ساعت تعریف شده پشتیبانی می کند. اگر بخواهیم صفحه ای بسازیم پنج ساعت جلوتر را نشان دهد باید یک تابع View و URLconf برای آن ایجاد کنیم، که کاری تکراری می باشد. نیاز به مقداری اختصار در اینجا داریم.

سخنی درباره URL های بهینه

اگر با برنامه های دیگر توسعه ی وب نظیر Java و یا PHP کار کرده باشید، شاید این فکر به نظر شما خطور کند که باید از یک پارامتر query string استفاده کنید، مانند /time/plus?hours=3، بدین شکل که ساعت مورد نظر را درون پارامتر query string همانطور که نشان داده شد بعد از علامت (?) ارسال کنید.

شما می توانید این مورد را با جنگو پیاده سازی کنید (نحوه ی انجام آن در فرم به خوبی بیان شده است)، اما یکی از فلسفه های هسته ی جنگو این است که URL به صورت کاملا زیبا استفاده شوند. آدرس /time/plus/3/ به مراتب تمیزتر، ساده تر، خواناتر و خواندن آن آسانتر از query string می باشد. URL های زیبا مشخصه ی کیفیت برنامه ی وب می باشند.

حالا چطور می توان ساعت مشخص شده در URL را درون برنامه کنترل کرد؟ همانطور که پیش تر ذکر شد، URLpattern یک regular expression می باشد؛ از این رو، ما می توانیم از الگوی \d+ برای مچ کردن یک یا بیشتر ارقام استفاده کنیم.

urlpatterns = patterns('',
    # ...
    (r'^time/plus/\d+/$', hours_ahead),
    # ...
)

(ما از # ... برای اشاره کردن به این موضوع که ممکن است URLpattern های دیگری نیز درون مثال وجود داشته باشند استفاده می کنیم.)

این URLpattern جدید با هر آدرسی مانند /time/plus/2/، /time/plus/25/ یا حتی /time/plus/100000000/ مچ می شود. بهتر آن است که عدد وارد شده برای ساعت را محدود کنیم، به طوری که حداکثر عددی که بتوان وارد کرد 99 باشد. این بدین معنی است که می خواهیم تنها به وارد کردن اعداد یک یا دو رقمی اکتفا کنیم، شکل آن در regular expression بدین شکل خواهد بود \d{1,2}:

(r'^time/plus/\d{1,2}/$', hours_ahead),

نکته

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

یکی از جزئیات مهمی که معرفی شده است در اینجا حرف r می باشد که قبل URL استفاده شده است. این حرف به پایتون می گوید که رشته ی بعد از آن یک raw string می باشد، در این نوع رشته علامت (\) ترجمه یا تفسیر نمی شود. در رشته های معمولی پایتون علامت های (\) به حروف ویژه تفسیر می شوند مانند '\n'، که به یک کاراکتر خط جدید تبدیل می شود. هنگامی که از حرف r قبل یک رشته استفاده شود، مفسر پایتون دیگر علامت های (\) را تفسیر نمی کند، بنابراین r'\n' دیگر یک کاراکتر خط جدید نمی باشد و تنها دو کاراکتر می باشد، یک (\) و یک حرف کوچک n. بین کاربرد علامت (\) در پایتون و regular expression یک برخورد طبیعی وجود دارد، بنابراین شدیدا پیشنهاد می شود که هنگامی که می خواهید از regular expression استفاده کنید حتما از raw string ها استفاده کنید. از حالا به بعد، تمام URLpattern ها در این کتاب به صورت raw string خواهند بود.

اکنون که توانستیم توسط یک URL چندین URL مختلف را در URLpattern پشتیبانی کنیم، این مشکل مطرح می شود که چگونه داده مورد نظر در URL را به تابع view انتقال دهیم، به طوری که توسط یک تابع view تمام ساعت ها را کنترل کنیم. این مشکل با قرار دادن پرانتز به دور داده ی مورد نظر در URLpattern قابل حل می باشد. برای مثال فوق، ما می خواهیم شماره ی وارد شده در URL را به تابع view انتقال دهیم، بنابراین عبارت \d{1,2} را درون پرانتز قرار می دهیم:

(r'^time/plus/(\d{1,2})/$', hours_ahead),

آخرین URLconf شامل دو تابع view قبلی می باشد:

from django.conf.urls.defaults import *
from mysite.views import hello, current_datetime, hours_ahead

urlpatterns = patterns('',
    (r'^hello/$', hello),
    (r'^time/$', current_datetime),
    (r'^time/plus/(\d{1,2})/$', hours_ahead),
)

نظر بدهید

توجه: HTML ترجمه نمی شود!

امتیاز بد           خوب

ترتیب کد نویسی

در مثال فوق، ابتدا URLpattern نوشته شد و بعد تابع view، اما در مثال های قبل از آن، ابتدا تابع view نوشته شد و بعد URLconf. کدام تکنیک بهتر است؟

روش هر توسعه دهنده متفاوت است.

اگر شما از جمله افراد با مهارت هستید، ممکن است هنگام شروع پروژه ابتدا URLpattern های برنامه ی خود را نوشته و سپس به view های برنامه بپردازید. این روش به دلیل دادن به اصطلاح یک نوع لیست کاری واضح به شما مفید می باشد و اساسا پارامتر های مورد نیاز برای view را در ابتدای کار تعریف می کند.

اگر شما از جمله برنامه نویسانی می باشید که دوست دارند از جزئیات به کلیات جلو بروند، ممکن است ترجیح بدهید ابتدا view ها را بنویسید و سپس URL ها را به آنها مرتبط کنید. این روش نیز مانند روش قبل می تواند مناسب باشد.

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

حالا تابع hours_ahead را ایجاد خواهیم کرد که در URLconf با URL مورد نظر یعنی r'^time/plus/(\d{1,2})/$' مرتبط شده است. تابع hours_ahead بسیار شبیه به تابع current_datetime می باشد که در ابتدا نوشته شده است، با یک تفاوت کلیدی: تابع مذکور (hours_ahead) یک آرگومنت اضافه دریافت می کند، که شماره ی ساعت ها می باشد:

from django.http import Http404, HttpResponse
import datetime
def hours_ahead(request, offset):
    try:
        offset = int(offset)
    except ValueError:
        raise Http404()
    dt = datetime.datetime.now() + datetime.timedelta(hours=offset)
    html = "<html><body>In %s hour(s), it will be %s.</body></html>" % (offset, dt)
    return HttpResponse(html)

اجازه دهید کد فوق را مورد بررسی قرار دهیم:

  • تابع view، hours_ahead، دو پارامتر دریافت می کند: request و offset.
    • request همانطور که در تابع hello و current_datetime مشاهده کردید یک شیء HttpRequest می باشد. دوباره می گوییم که هر تابع view همیشه یک شیء HttpRequest به عنوان اولین پارامتر دریافت می کند.
    • offset یک رشته است که داخل URLpattern درون پرانتز قرار گرفته است. به عنوان مثال، اگر URL درخواست شده /time/plus/3/ باشد، بنابراین offset رشته ی '3' خواهد بود. اگر URL درخواست شده /time/plus/21/ باشد، بنابراین offset رشته ی '21' خواهد بود. نکته اینکه مقدار که در URLpattern داخل پرانتز قرار گرفته شده است همواره رشته خواهد بود، نه Integer، حتی اگر رشته ی مورد نظر تنها از ارقام ساخته شده باشد مانند '21'.

      (از نظر فنی، مقدار درون پرانتز در URLpattern همواره شیء یونیکد می باشد، نه رشته ی ساده ی پایتون، ولی در حال حاضر درباره ی این فرق نگران نباشید.)

      در این مثال فوق متغیر مورد نظر offset نامیده شده است، شما می توانید آن را هر چیزی که دوست دارید نام گذاری کنید، البته هر نامی در محدوده ی نام گذاری متغیرهای پایتون. نام متغیر به هیچ وجه مهم نمی باشد، تنها چیز مهم این است که، این متغیر به عنوان دومین پارامتر تابع view بعد از request باشد. (همچنین می توان آنرا به صورت کلمه ی کلیدی نیز بکار برد که در آموزش view و urlconf پیشرفته درباره ی آن صحبت شده است.)

  • اولین چیزی که درون تابع انجام شده است استفاده از int() و قرار دادن offset درون آن می باشد. این عمل مقدار یک رشته را به یک integer تبدیل می کند.

    توجه داشته باشید در صورتیکه پایتون قادر به تبدیل مقدار رشته به یک integer نباشد، به عنوان مثال اگر مقدار رشته چیزی شبیه به این باشد 'foo'، در این حالت خطای ValueError ایجاد خواهد شد. در مثال فوق، در صورتیکه برنامه با خطای ValueError برخورد کند، استثناء (exception) django.http.Http404 ایجاد خواهد شد، که نمایش صفحه ی خطای "Page not found" می باشد.

    خوانندگان هوشیار تعجب خواهند کرد که چگونه می توان به خطای ValueError رسید، در حالی که regular expression در URLpattern (\d{1,2}) تنها ارقام را قبول خواهد کرد، و offset همیشه تنها رشته ی ساخته شده از ارقام خواهد بود؟ جواب این است یک تابع view هیچگونه فرضی نسبت به پارامترهای ورودی خود در این حالت نخواهد کرد و با چک کردن مقدار متغیر درون تابع view به اصطلاح یک محکم کاری نسبت به مقدار متغیر ایجاد خواهد شد، همچنین اگر مبحث loosely coupling را به خاطر بیاورید تابع view جدای از URLconf به کار خود می پردازد.

  • در خط بعدی از تابع، زمان و تاریخ فعلی محاسبه شده و شماره ساعت مناسب به آن اضافه شده است. عبارت datetime.datetime.now() را درون تابع current_datetime قبلا مشاهده کرده اید؛ مفهوم جدید در اینجا این است که می توانید با ساختن و اضافه کردن شیء datetime.timedelta به یک شیء datetime.datetime زمان و تاریخ را حساب کرده و نمایش دهید. در نهایت نتیجه این عمل درون متغیر dt ذخیره شده است.

    این خط دلیل استفاده از int() را نشان می دهد، چرا که برای استفاده از تابع datetime.timedelta باید پارامتر hours یک integer باشد.

  • در قدم بعدی، یک خروجی HTML ساخته شده است، همانطور که در تابع current_datetime مشاهده کردید. تنها تفاوت این است که در اینجا از قابلیت format-string پایتون با دو مقدار استفاده شده است، نه یک مقدار. از این رو دو علامت %s درون رشته و یک تاپل برای درج مقدایر در انتها وجود دارد.
  • نهایتا، یک HttpResponse از HTML برگردانده شده است.

با تابع view و URLconf نوشته شده، سرور جنگو را (اگر در حال اجرا نمی باشد) اجرا کنید، و به منظور بررسی اینکه برنامه کار می کند یا خیر به آدرس http://127.0.0.1:8000/time/plus/3/ بروید. سپس به آدرس http://127.0.0.1:8000/time/plus/5/ رفته و همچنین آدرس http://127.0.0.1:8000/time/plus/24/ را نیز امتحان کنید. نهایتا به منظور بررسی اینکه الگوی شما تنها اعداد یک رقمی و دو رقمی را قبول می کند آدرس http://127.0.0.1:8000/time/plus/100/ را نیز امتحان کنید؛ جنگو باید خطای "Page not found" را در این مورد نمایش دهد. همچنین آدرس http://127.0.0.1:8000/time/plus/ (بدون هیچ ساعت تعیین شده ای) نیز باید باعث بروز خطای 404 شود.

  صفحات خطای جالب جنگو

چند لحظه ای از برنامه های وبی که تاکنون ساخته ایم لذت ببرید ... حالا بیایید خرابشان کنیم! بیایید به طور عمد یکی از خطاهای پایتون را درون فایل views.py با کامنت کردن عبارت offset = int(offset) در hours_ahead معرفی کنیم.

def hours_ahead(request, offset):
    # try:
    #     offset = int(offset)
    # except ValueError:
    #     raise Http404()
    dt = datetime.datetime.now() + datetime.timedelta(hours=offset)
    html = "<html><body>In %s hour(s), it will be %s.</body></html>" % (offset, dt)
    return HttpResponse(html)

سرور جنگو را (اگر در حال اجرا نیست) اجرا کرده و به آدرس /time/plus/3/ بروید. یک صفحه ی خطا با یک مقدار قابل توجهی از اطلاعات را مشاهده خواهید کرد، که همچنین در بالای صفحه پیام TypeError نمایش داده شده است:
"unsupported type for timedelta hours component: Unicode"

چه اتفاقی افتاد؟ تابع datetime.timedelta انتظار دارد پارامتر hours یک integer باشد، و در کد فوق قسمتی از کد که offset را به integer تبدیل می کرد کامنت شده است، که باعث شده است در عبارت datetime.timedelta خطای TypeError ایجاد شود.

هدف از این مثال نشان دادن صفحه ی خطای جنگو بود. مقداری درون صفحه ی خطا بگردید و با اطلاعات مختلف داده شده آشنا شوید.

مسائل قابل توجهی در اینجا وجود دارند:

  • در بالای صفحه، اطلاعات کلیدی در مورد استثناء (exception) بدست می آورید: نوع استثناء، پارامترهای استثناء (در این مورد پیام "unsupported type")، فایلی که استثناء در آن ایجاد شده است، و شماره ی خط آن.
  • در زیر اطلاعات کلیدی استثناء، صفحه traceback کامل پایتون را برای این استثناء نمایش می دهد. این همانند traceback استانداردی است که در خط فرمان interpreter نشان داده می شود، که در اینجا حالت تعاملی بیشتری دارد. برای هر سطح ("frame") در توده های مشخص، جنگو نام فایل، نام متد/تابع، شماره ی خط، و سورس کد خط مورد نظر را نمایش می دهد.

    بر روی خط خاکستری تیره رنگ کد کلیک کنید، خط های قبل و بعد خطی که باعث بروز خطا شده است را مشاهده خواهید کرد.

    بر روی "local vars" در زیر هر frame کلید کنید تا جدول تمام متغیرهای محلی و مقادیرشان نشان داده شود. این اطلاعات اشکال زدایی می تواند یک کمک بزرگ برای هر توسعه دهنده باشد.

  • بر روی "local vars" در زیر هر frame کلید کنید تا جدول تمام متغیرهای محلی و مقادیرشان نشان داده شود. این اطلاعات اشکال زدایی می تواند یک کمک بزرگ برای هر توسعه دهنده باشد.

    در قسمت پایین دکمه ی "Share this traceback on a public Web site" اطلاعات traceback را درون سایت http://www.dpaste.com/ تنها با یک کلیک کپی می کند و شما می توانید URL آن سایت را برای مشاهده ی traceback شما به دیگران بدهید.

  • در قسمت پایین دکمه ی "Share this traceback on a public Web site" اطلاعات traceback را درون سایت http://www.dpaste.com/ تنها با یک کلیک کپی می کند و شما می توانید URL آن سایت را برای مشاهده ی traceback شما به دیگران بدهید.

    زیر قسمت "Request information"، بخش "Settings" قرار دارد که لیست تمام تنظیمات انجام شده ی جنگو می باشد. (قسمت ROOT_URLCONF پیش تر بیان شده است، و تنظیمات مختلف دیگر جنگو در سراسر کتاب نشان داده خواهد شد.)

صفحه ی خطای جنگو برای نشان دادن اطلاعات بیشتر موارد ویژه، از قبیل خطاهای template syntax بسیار توانا می باشد. در زمان بحث در مورد سیستم tamplate جنگو به این موضوع خواهیم پرداخت. برای حالا، خط offset = int(offset) را از حالت کامنت خارج کنید تا تابع view بتواند دوباره کار کند.

آیا شما از آن دسته از برنامه نویسانی هستید که دوست دارید برنامه ی خود را با قرار دادن عبارت print اشکال زدایی کنید؟ شما می توانید برای انجام چنین کاری بدون بکار بردن عبارت print از صفحه ی خطای جنگو استفاده کنید. در هر نقطه ای از view به صورت موقت یک assert False قرار دهید. سپس شما می توانید متغیرهای محلی و وضعیت برنامه را مشاهده کنید:

def hours_ahead(request, offset):
    try:
        offset = int(offset)
    except ValueError:
        raise Http404()
    dt = datetime.datetime.now() + datetime.timedelta(hours=offset)
    assert False
    html = "<html><body>In %s hour(s), it will be %s.</body></html>" % (offset, dt)
    return HttpResponse(html)

در پایان، واضح است که بسیاری از اطلاعات حساس هستند، و این موضوع که اطلاعات داخلی کد پایتون و تنظیمات جنگو را برای عموم نشان شود کاری ابلهانه می باشد. افراد مخرب می توانند با استفاده از این اطلاعات دست به کارهای نامطلوبی بزنند. به این دلیل، صفحه ی خطای جنگو تنها زمانی نمایش داده می شود که پروژه ی جنگو در حالت debug باشد. نحوه ی غیر فعال کردن حالت debug در فصل دوازدهم توضیح داده خواهد شد. در حال حاضر، دانستن اینکه هر پروژه ی جنگویی در هنگام ساخت به طور پیشفرض در حال debug می باشد. کافی است.

 

Has no item to show!