آموزش جنگو (Basic) : جلسه هفت | views و urls

در این جلسه به بررسی مفهوم views یا نماها و آدرس ها یا urls خواهیم پرداخت . با ما همراه باشید .آموزش جنگو : جلسه هفت | نماها یا Viewsنماها یا Viewsمفهوم یک View در حقیقت یک صفحه از وبسایت شما است که به طور کلی یک تابع (function) و یک تمپلیت یا قالب (template) را درون خود نگه داری میکند .یک وبلاگ میتواند دارای view های زیر باشد .صفحه ی خانه – مقالات اخیر را به کاربر نشان می دهد .صفحه جزییات – خود مقاله و جزییات آن را به کاربر میدهد .صفحه بیس سایت – تمام مقالات را نشان می دهد .صفحه اکانت کاربری – مدیریت کاربران را ارایه میدهد .مثالی بهتر : برای مثال وبسایت دیجی کالا دارای چندین ویو (view) است , ویو مربوط به صفحه خانه , جزییات محصول , فیلتر محصولات , ورود و ثبت نام کاربر , اطلاع رسانی ها و …وبسایتی که هم اکنون در حال ساخت آن هستیم چند view خواهد داشت . این وبسایت یک وبسایت سوال و جواب است و سوال های مربوطه را به شما با جواب و رای های آنها نشان میدهد . چیزی مانند وبسایت https://stackoverflow.comویو مربوط به صفحه index یا همان home :چندین question یا سوال های آخر را نشان می دهد .ویو مربوط به صفحه جزییات سوال :جزییات یا question_textمربوط به سوال را نشان می دهد . همچنین یک فرم htmlبه شما نشان می دهد تا بتوانید رای خود را ثبت کنید . اما این ویو جواب مربوط به سوال را نشان نمیدهد.ویو مربوط به صفحه resultیا جواب سوال :پاسخ مربوط به یک سوال خاص را به شما نشان می دهد .ویو مربوط به رای دادن :رای های مربوط بهب هر سوال را کنترل میکند . (برای مثال شما به یکی از سوالات رای مثبت دادید یا رای منفی)در جنگو، صفحات وب و سایر محتواها توسط view یا همان ویو ارائه می شود. هر نما یا صفحه از وب با یک تابع پایتون (یا روشی دیگر که بعدا در مورد آن صحبت خواهیم کرد ، نماهای مبتنی بر کلاس) نشان داده می شود. جنگو با بررسی URL درخواستی (به طور دقیق، بخشی از URL بعد از نام دامنه) یک نما (view) و سپس تابع مربوط به آن را انتخاب میکند.شاید در جستجوی های خود در اینترنت با ادرس هایی همچون ME2/Sites/dirmod.htm?sid=&type=gen&mod=Core+Pages&gid=A6CD4967199A42D9B65B1B رو به رو شده باشید . خبر خوب این است که جنگو این گونه نیست و url های زیباتری برای وبسایت شما ارائه میدهد .ابتدا قبل از بررسی یک url در جنگو بیایید به بررسی url pattern بپردازیم .یک url pattern یک الگوی تعریف شده برای یک url یا آدرس صفحه ای از وب است . برای مثال : <newspaper/<month>/<yearبرای مثال در url pattern بالا شما یک بخش از وبسایت را با نام newspaper تعریف کرده اید . این بخش ثابت است ولی بخش های دیگر مانند <month> میتوانند متغییر باشند و وابسته به آن میتوانید شما یک محتوا را به کاربر نشان دهید .نکته :شاید اکنون چیزی نفهمید ولی به مرور که پروژه هایمان را پیش میبریم بیشتر منظور این جملات را متوجه میشید . پس اگر بخشی از مقالات را متوجه نشدید نگران نباشید .بسیار خب , آیا شکل زیر را به یاد دارید ؟معماری MVT در جنگوشما اکنون مفهوم view و model را درک کردید . در شکل بالا , برای اینکه جنگو از یک url به یک view برسد ,از تنظیماتی با نام UrlConf استفاده میکند . یک UrlConf به شما الگوی نشان دادن و استفاده از یک url را ارائه میکند .ساخت Views و ایجاد آدرس (url) آنما قبلا یک viewدر اپ poll ایجاد کرده بودیم ولی اکنون بیایید چندین view دیگر نیز در فایل polls/views.py ایجاد کنیم . (هر تابعی که مقدار request را به عنوان argument دریافت کند ,با نام یک view شناخته می شود! )def detail(request, question_id): return HttpResponse(&quotYou're looking at question %s.&quot % question_id) def results(request, question_id): response = &quotYou're looking at the results of question %s.&quot return HttpResponse(response % question_id) def vote(request, question_id): return HttpResponse(&quotYou're voting on question %s.&quot % question_id)حال باید به وسیله تابع path ادرس یا url مربوط به این سه ویو (view) را به جنگو بشناسانیم.from django.urls import path from . import views urlpatterns = [ # ex: /polls/ path('', views.index, name='index'), # ex: /polls/5/ path('<int:question_id>/', views.detail, name='detail'), # ex: /polls/5/results/ path('<int:question_id>/results/', views.results, name='results'), # ex: /polls/5/vote/ path('<int:question_id>/vote/', views.vote, name='vote'), ]بسیار خب ,شما با تابع path از قبل اشنا شده اید . این تابع در آرگومان (argument) اول خود مقداری را با نام route یا مسیر دریافت می کند . این مقدار به همان مسیر شما که در مرورگر باز می شود ,اشاره دارد .برای مثال آدرس :Index => 127.0.0.1:8000/detail => 127.0.0.1:8000/2results => 127.0.0.1:8000/2/resultvote => 127.0.0.1:8000/2/voteاشاره دارند . (مقدار ادرس در سمت راست قرار گرفته است و به این معناست که این ادرس در مرورگر شما به جنگو درخواستی را ارسال میکند که تابعی را اجرا کند . در سمت چپ تابع مورد نظر برای هر ادرس که در path و فایل polls.urls مشخص شده است ,نشان داده شده است .)البته این را توجه داشته باشید که 127.0.0.1:8000 ادرس لوکال هاست شما است و هیچ ربطی به مسیردهی جنگو ندارد . زمانی که وبسایت واقعی را بخواهید بسازید مقدار ان با دامنه سایت جایگزین میشود . برای مثال: example.com/2/detailاکنون مرورگر خود را باز کنید و به ادرس 127.0.0.1:8000/1 بروید (اگر با ارور مواجه شدید عدد 2 را با عدد 1 جایگزین کنید) .در این هنگام تابع detail برای شما اجرا خواهد شد و شما پیامی تحت عنوان you are looking at question 1 را خواهید دید . اگر نمیدانید هنوز چه اتفاقی افتاده است , به مراحل زیر خوب توجه کنید تا ببینید در جنگو دقیقا چه اتفاقی افتاد .1 – شما اکنون از ادرس 127.0.0.1:8000/1 بازدید کردید .2- جنگو درخواست یا request را از سوی شما دریافت کرد و با استفاده از ادرسی که به ان درخواست ارسال شده است تابعی را که مربوط به همان ادرس است اجرا کرد .2-نکته-کلمه < int:question_id> در مقدار route به این معناست که کاراکتری از نوع int یا عدد صحیح برای ادرس ارسال خواهد شد و میتواند هر عددی باشد که در متغییری با نام question_id ذخیره خواهد کرد .3-تابع detail برای شما اجرا شد و مقادیر request و question_id را دریافت کرد .3-نکته-مقادیری که به ان در قبل اشاره شد به صورت ارگومان به تابع ارسال می شوند . همانطور که در تابع می بینید ,مقادیر به صورت ارگومان در ورودی تابع نوشته شده اند . detail(request, question_id)4-تابع ,خروجی ای را به صورت اینکه مقدار گرفته شده از طریق question_id را به همراه متنی ترکیب کند به ما باز میگرداند که نام آن responce است .5-خروجی به شما داده میشود و تمام !ساخت Viewهای متصل به دیتابیسدر view قبلی که ساختیم , شما فقط از طریق url مقداری را به تابع ارسال میکردید و تنها کاری که تابع میکرد این بود که خروجی را برای شما نمایش دهد که حاوی مقدار گرفته شده به همراه متنی دیگر است .اما بیایید تا ویوهایی بنویسیم که واقعا برای ما کاری مفید انجام دهند . برای این کار باید انها را به مدل ها و دیتابیسمان متصل کنیم .هرview مسئول انجام یکی از این دو کار است : بازگرداندن یک شی یا HttpResponse که حاوی محتوای صفحه درخواستی است یا ایجاد یک Responce مانند HTTP404 که نشان دهنده این است که صفحه ی مورد نظر به شما نمایش داده نمی شود . بقیه کار ها و عملیات هایی که انجام می شوند به خودتان مربوط است .سخن هایی که در بالا زده شد به این معناست که شما در یک view میتوانید هر کاری که می خواهید انجام دهید ولی در اخر باید Response یا نتیجه ای را به کاربر بازگردانید . در غیر این صورت شما با ارور مواجه خواهید شد . این Responce میتواند ارور 404 یا هر چیز دیگری مانند یک ریدایرکت و یا یک صفحه html باشد . (بیشتر آدرس ها همان صفحه html را به شما باز میگردانند )ولی قبل از اینکه به کاربر خروجی یا Responce را ارائه کنید ,میتوانید سری کارهایی را انجام دهید . برای مثال به دیتابیس متصل شوید ,رکوردی را از ان بخوانید و اطلاعات ان رکورد را به کاربر نشان دهید و یا میتوانید با توجه به رکورد یک فایل pdf یا xml بسازید و به کاربر نشان دهید و یا ...ولی در اخر چیزی که جنگو نیاز دارد یک responce است .اجازه دهید تا با دیتابیس خود جنگو فعلا به جلو حرکت کنیم . تابع index را به این صورت تغییر دهید . این تابع 5 سوال اخر را به شما نمایش خواهد داد .from django.http import HttpResponse from .models import Question def index(request): latest_question_list = Question.objects.order_by('-pub_date')[:5] output = ', '.join([q.question_text for q in latest_question_list]) return HttpResponse(output) # Leave the rest of the views (detail, results, vote) unchangedدر اینجا ابتدا ما مدل Question و تابع htppResponce را import کردیم که در ادامه به انها نیاز داریم . سپس تابع index را که از قبل ساخته بودیم تغییر دادیم . جنگو هنگامی که به ان request ارسال میشود با توجه به آن , در فایل urls جستجو میکند و این تابع را پیدا میکند . در خط اول این تابع متغییری را تعریف کردیم و مقدار درون آن یک query set است که در ادامه آن را توضیح خواهیم داد . (به عبارت دیگر نوع داده ای است که حاوی تمام شی ها و رکورد های ماست که ویژگی مشخصی را دارا هستند .) در ادامه از مدل و جدول Question ما متد order_by را فراخوانی کردیم .این متد شی هایی که ویژگی خاصی دارند را برای ما پیدا میکند و انها را مرتب میکند (بعدا با تمامی متد ها اشنا خواهید شد . فعلا دست و پا شکسته به ادامه کار می پردازیم تا ابتدا روش استفاده از این متد ها دستتان بیاید .) . در اینجا شی هایی از کلاس Question که فیلد pub_date آنها جدید است پیدا میشود . علامت – در پشت pub_date به این معناست که این فیلد از کوچترین زمان و جدیدترین آنها بررسی و مرتب شود . سپس با [:5] 5 تای اول آنها را جدا میکنیم و درون متغییر ذخیره سازی میکنیم .در خط بعدی ما رشته ای را ایجاد کردیم و از انجا که متغییر latest_question_list دارای چندین شی است , پس از حلقه for استفاده میکنیم و درون رشته , output مقدار question_text هر شی را درون آن رشته میریزیم . در آخر با استفاده از HttpResponce رشته را به کاربر باز میگردانیم .اما اگر الان از صفحه http://127.0.0.1:8000 بازدید کنید متوجه خواهید شد که شیوه نمایش سوالات بسیار بهم ریخته است و سایت های دیگر اینگونه نیستند . برای همین منظور شما باید از html و css برای زیباسازی اطلاعات خروجی و response خود استفاده کنید . در واقع باید به حای یک httpResponce یک سند html را به کاربر بازگردانید .برای اینکار جنگو از سیستم تمپلیت استفاده میکند . (template system) در این کتاب ما از سیستم دیفالت و سیستمی که خود جنگو برای ما طراحی کرده است استفاده میکنیم .گرچه تعدادی دیگر از template system وجود دارند اما بهتر است ابتدا با template system خود جنگو (پیش فرض) آشنا شوید .در این جلسه به بررسی نحوه کار با نماها (views) و نحوه اتصال آدرس ها به آنها پرداختیم . در جلسه بعدی نحوه کار با تمپلیت ها را بررسی خواهیم کرد .