اسلاگ یا معادل فارسی آن "نامک" بخشی از url است که در بعضی از صفحات وب قابل مشاهده می باشد. الگوی یک نامک ترکیبی از حروف ارقام و خط تیر یا آندرلاین می باشد.
در جنگو از نامک برای متمایز کردن رکورد های بعضی از جداول استفاده می شود که توسط آن نامک می توان به detail_view آن رکورد ها دسترسی پیدا کرد. برای مثال در یک سایت فروشگاهی می توان به دسته بندی های محصولات و خود محصولات نامک اختصاص داد.
نامک دسته بندی: apple_phones
نامک محصول: iphone_14_pro_max
از آنجایی که از نامک برای دسترسی به DetailView استفاده می شود. بدیهی است که نامک می بایست در سطح جدول unique باشد. حال فرض کنید می خواهیم برای پست ها در وبلاگمان از نامک استفاده کنیم. باید یک فیلد برای نگه داری نامک در دیتابیس در مدل مربوط به پست در نظر بگیریم که جنگو برای تعریف فیلد نامک در مدل برای ما SlugField را تعبیه کرده است. به عنوان مثال به قطعه کد زیر نگاه کنید.
class Post(models.Model):
title = models.CharField(
max_length=100,
)
slug = models.SlugField(
max_length=100,
unique=True,
)
آرگومان max_length برای SlugField الزامی می باشد زیر از CharField ارثبری می کند.
برای مقدار دهی به نامک می توان به دو طریق عمل کرد:
برای اینکه نامک بصورت پیشفرض مقدار دهی شود دو روش معرفی می کنیم:
prepopulated_fields یک کلاس اتریبیوت برای کلاس ModelAdmin می باشد که با الگوی زیر قابل استفاده است. به قطعه کد زیر نگاه کنید.
class PostAdmin(admin.ModelAdmin):
list_display = ('title', 'slug')
prepopulated_fields = {
'slug': ('title',),
}
مقدار prepopulated_fields یک دیکشنری است که فیلد هایی که قرار است بصورت خودکار پر شوند، کلید های آن هستند و مقدار متناظر با هر کلید، لیست یا تاپلی از فیلد هایی است که قرار است با استفاده از آنها مقدار فیلد کلید پر شود. همانطور که در قطعه کد بالا مشاهد می کنیم قرار است که نامک بر اساس عنوان پست پر شود. این قابلیت با استفاده از جاواسکریپت پیاده سازی شده است و همزمان با تایپ کردن عنوان، متوجه این امر می شوید که نامک در حال پر شدن است.
در این روش می توانیم الگوریتم مورد نظر خود برای ایجاد نامک استفاده کنیم. برای اینکار متد save مدل پست را override می کنیم و قبل از ذخیره شدن در پایگاه داده (فراخوانی super().save )، نامک را مقدار دهی می کنیم. در اینجا با استفاده از فیلد title , مقدار فیلد slug را تولید کرده ایم. همانطور که مشاهده می کنیم از تابع slugify استفاده شده است.
class Post(models.Model):
title = models.CharField(
max_length=100,
)
slug = models.SlugField(
max_length=100,
unique=True,
)
def __str__(self):
return self.title
def save(self, **kwargs):
self.slug = slugify(self.title)
super().save(**kwargs)
این تابع یک رشته را دریافت کرده و با استفاده از آن یک نامک معتبر تولید می کند. برای import کردن این تابع همانند قطعه کد زیر عمل کنید.
from django.utils.text import slugify
از آنجا که نامک یک بخش متغیر در url می باشد، می بایست در آدرس دهی ها یک متغیر برای نامک لحاظ کنیم. به عنوان نمونه به قطعه کد زیر نگاه کنید.
path('<slug:post_slug>/', views.post_detail_view, name='post_detail'),
همانطور برای متغیر های عددی و رشته ای در آدرس می توان نوع را مشخص کرد (int, str)، برای نامک هم می توان نوع آن را مشخص کرد.
<slug:variable_name>
مقدار نامک با اسمی که ما برای متغیر در آدرس تعریف کردیم به view ما ارسال می شود. از این رو اگر از view های تابعی استفاده می کنید، view شما باید یک آرگومان هم نام اسم متغیری که در url تعریف کردید، دریافت
کند و یا آرگومان های نامدار (**kwargs) بپذیرد. اگر هم در view های کلاسی متدی را override می کنید، مثل متد های get, post و .. باید این نکته را رعایت کنید.
def post_detail_view(request, post_slug):
post = get_object_or_404(Post, slug=post_slug)
context = {
'post': post,
}
return render(request, 'blog/post_detail.html', context)
class PostDetailView(generic.DetailView):
slug_url_kwarg = 'post_slug'
model = Post
template_name = 'blog/post_detail.html'
در view های کلاسی generic که با یک رکورد از پایگاه داده سروکار دارند مثل DetailView, UpdateView و DeleteView، پیش فرض جنگو استفاده از pk می باشد. اما کد های این view ها طوری نوشته شده اند که با یک تغییر کوچک می توان کاری کرد که بتوان با دو روش دیگر یعنی صرفا با نامک و ترکیب نامک و pk به پست مورد نظر دسترسی پیدا کرد و آن تغییر مقدار دهی کلاس اتریبیوت slug_url_kwarg می باشد. مقدار آن باید اسم متغیر نامک در url باشد که در مثال ها مذکور post_slug بود. اینکه بخواهید صرفا نامک باشد یا هم نامک و هم pk، صرفا در آدرس دهی ها مشخص می شود. بقیه کار ها توسط view های generic انجام خواهد شد.
path('<int:pk>/<slug:post_slug>/', ...)
path('<slug:post_slug>/', ...)
اگر فکر می کنید که ما چیزی را در این مقاله جا انداخته ایم و یا در مورد پست های بعدی ایده و یا نظری دارید، خوشحال می شویم که این مورد را با ما در میان بگذارید. تنها کافیست روی دکمه زیر کلیک کنید و پیشنهاد خود را ارسال کنید.
عالی آقای طاهری
mehdi
9 آذر 1401, 19:58