URLهای پیشرفته

سلام

برای ساخت آدرس‌های پویا استفاده می شود. برای مثال ساخت آدرس پروفایل‌ها که در آن می‌خواهیم نام کاربر در آدرس قرار گیرد و او را به صفحۀ خود ارجاع دهد. مثل http://twitter.com/Libogram. برای این کار به شکل زیر عمل می کنیم:

from django.conf.urls import url
from boards import views

urlpatterns = [
    url(r'^$', views.home, name='home'),
    url(r'^(?P<username>[\w.@+-]+)/$', views.user_profile, name='user_profile'),
]

با توجه به اینکه گفته شد در فایل urls.py بعد از اولین تطبیق، جنگو به کار خود پایان می دهد بنابراین در صورتی که ما یک صفحه به نام about  داشته باشیم و همزمان کاربری نیز با نام about وجود داشته باشد؛ تکلیف چیست؟

یک راه این است که به جای عبارت بالا قبل از آدرس پروفایل یک مسیر انتزاعی با نام /username/ ایجاد کنیم یا مثل بعضی از سایت‌ها قبل از حساب کاربری یک @ قرار دهیم. مثل http://mysite.com/@Libogram که البته در بسیاری از سایت‌های بزرگ مرسوم نیست. مخلص کلام اینکه باید قبل از ساخت آدرس بالا، آدرس صفحۀ about را مشخص کنیم.

from django.conf.urls import url
from boards import views

urlpatterns = [
    url(r'^$', views.home, name='home'),
    url(r'^about/$', views.about, name='about'),
    url(r'^(?P<username>[\w.@+-]+)/$', views.user_profile, name='user_profile'),
]

نکته اینکه  اگر کاربری با نام about وجود داشته باشد نمی‌تواند صفحۀ پروفایل خود را از این طریق مشاهده کند!! این اتفاق در گیت‌هاب افتاده و کاربری با نام watching وجود دارد که نمی تواند صفحۀ خود را مستقیماً ببیند!

البته بهترین راه این است که یک بلک لیست برای نام کاربران وجود داشته باشد و کسی نتواند آن‌ها را رزرو یا ایجاد کند. لیستی از این نام‌های کاربری را می توان در آدرس‌ زیر یافت:

https://github.com/shouldbee/reserved-usernames/blob/master/reserved-usernames.csv

مثالی از نحوۀ پیاده‌سازی آن هم در جنگو در آدرس https://github.com/vitorfs/parsifal/blob/master/parsifal/authentication/forms.py#L6 وجود دارد.

برگردیم به پروژۀ خودمان. قصد داریم با استفاده از آیدیِ یک بورد، لیستِ تاپیک‌های آن بورد را نمایش دهیم.

url(r'^boards/(?P<pk>\d+)/$', views.board_topics, name='board_topics')

ریجکس \d+ به عنوان integer است. این عدد برای مشخص‌کردن و بیرون‌کشیدن بورد از دیتابیس کارآیی دارد. همچنین ریجکس (?P<pk>\d+) به این معناست که این عدد را در متغیر pk قرار دهد. در تابع view نیز برای استفاده از این متغیر به شکل زیر عمل می کنیم:

def board_topics(request, pk):
    # do something...

با توجه به اینکه از ریجکس (?P<pk>\d+) استفاده شده در تابعِ ویو نیز حتماً باید از همین اسم استفاده کنیم. اگر نخواهیم خودمان را به این اسم مقید کنیم نباید در ریجکس متغیری را تعریف کنیم. یعنی:

url(r'^boards/(\d+)/$', views.board_topics, name='board_topics')

و حالا در تابعِ view از هر نامی می‌شود استفاده کرد. مثلاً:

def board_topics(request, board_id):
    # do something...

یا:

def board_topics(request, id):
    # do something...

نکته: pk به نمایندگی از primary key آمده است. جنگو به صورت خودکار برای هر مدل، یک فید از نوع AutoField با نام id ایجاد می‌کند که این فیلد به عنوان کلید اصلی در نظر گرفته می‌شود. اما اگر بخواهیم برای یک مدل کلید اصلی دیگری مثل ایمیل اختصاص دهیم باید به صورت جداگانه آن را مشخص کنیم. برای دسترسی به آن هم که باید از email یا نظیر آن استفاده شود.

ترجمۀ اختصاصی توسط تمدن

 

مطلب بعدی: استفاده از APIها در URL

مطلب قبلی: URLهای ابتدایی و ساده 

0 پاسخ

دیدگاه خود را ثبت کنید

تمایل دارید در گفتگو شرکت کنید؟
نظری بدهید!

دیدگاهتان را بنویسید

نشانی ایمیل شما منتشر نخواهد شد. بخش‌های موردنیاز علامت‌گذاری شده‌اند *