Django Slug 欄位
什麼是 Slug?
您是否見過如下所示的 URL?
w3schools.com/django/learn-about-slug-field
"learn-about-slug-field" 部分就是一個 slug。
它是一個只包含字母、連字元、數字或下劃線的描述。
它常用於 URL 中,使其更易於閱讀,同時也更利於搜尋引擎最佳化。
不帶 Slug 的 URL
如果您跟隨我們在本教程中建立的 Django 專案,您會有一個如下所示的小型 Django 專案:
如果您點選第一個成員,您將跳轉到這個頁面:
請看位址列:
127.0.0.1:8000/members/details/1
數字 "1" 指的是資料庫中該特定記錄的 ID。
這對開發者來說很有意義,但對其他人可能不然。
帶 Slug 的 URL
如果 URL 看起來像這樣會更有意義:
請看位址列:
127.0.0.1:8000/members/details/emil-refsnes
這是一個對使用者更友好的 URL,Django 可以幫助您在專案中建立這樣的 URL。
修改 models.py 檔案
首先,在資料庫中新增一個新欄位。
開啟 models.py
檔案,新增一個名為 slug
的欄位,資料型別為 SlugField
。
my_tennis_club/members/models.py
:
from django.db import models
class Member(models.Model):
firstname = models.CharField(max_length=255)
lastname = models.CharField(max_length=255)
phone = models.IntegerField(null=True)
joined_date = models.DateField(null=True)
slug = models.SlugField(default="", null=False)
def __str__(self):
return f"{self.firstname} {self.lastname}"
這是模型結構的變更,因此我們必須進行遷移,告訴 Django 它需要更新資料庫。
py manage.py makemigrations
以及 migrate 命令:
py manage.py migrate
修改 Admin
現在我們在資料庫中有了一個新欄位,但我們還希望在設定成員的 firstname 或 lastname 時,這個欄位能自動更新。
這可以透過 Django 的一個內建功能 prepopulated_fields
來實現,您可以在其中指定要預填充的欄位,以及一個包含用於填充它的欄位的元組。
這在 admin.py
檔案中完成:
my_tennis_club/members/admin.py
:
from django.contrib import admin
from .models import Member
# Register your models here.
class MemberAdmin(admin.ModelAdmin):
list_display = ("firstname", "lastname", "joined_date",)
prepopulated_fields = {"slug": ("firstname", "lastname")}
admin.site.register(Member, MemberAdmin)
進入 Admin 介面並開啟一條記錄進行編輯:
點選“儲存”,"slug" 欄位將被自動填充為 firstname 和 lastname,並且由於 "slug" 欄位的型別是 SlugField,它將對值進行 "slugify" 處理,即在每個單詞之間加上連字元。
下次您開啟該成員進行編輯時,您會看到 slug 欄位及其值:
注意:由於新欄位預設是空的,您需要對每個成員執行此儲存操作。
修改模板
現在我們可以在整個專案中用 slug 欄位替換 ID 欄位。
從 all_members.html
模板開始,其中有指向詳情頁的連結。
my_tennis_club/members/templates/all_members.html
:
{% extends "master.html" %}
{% block title %}
My Tennis Club - List of all members
{% endblock %}
{% block content %}
<div class="mycard">
<h1>Members</h1>
<ul>
{% for x in mymembers %}
<li onclick="window.location = 'details/{{ x.slug }}'">{{ x.firstname }} {{ x.lastname }}</li>
{% endfor %}
</ul>
</div>
{% endblock %}
修改 URL
我們還需要在 urls.py
檔案中做一些修改。
將 <int:id>
改為 <slug:slug>
。
my_tennis_club/members/urls.py
:
from django.urls import path
from . import views
urlpatterns = [
path('', views.main, name='main'),
path('members/', views.members, name='members'),
path('members/details/<slug:slug>', views.details, name='details'),
path('testing/', views.testing, name='testing'),
]
修改檢視
最後,修改 details
檢視,使其將傳入的請求作為 slug 而不是 ID 來處理。
my_tennis_club/members/views.py
:
from django.http import HttpResponse
from django.template import loader
from .models import Member
def members(request):
mymembers = Member.objects.all().values()
template = loader.get_template('all_members.html')
context = {
'mymembers': mymembers,
}
return HttpResponse(template.render(context, request))
def details(request, slug):
mymember = Member.objects.get(slug=slug)
template = loader.get_template('details.html')
context = {
'mymember': mymember,
}
return HttpResponse(template.render(context, request))
def main(request):
template = loader.get_template('main.html')
return HttpResponse(template.render())
def testing(request):
template = loader.get_template('template.html')
context = {
'fruits': ['Apple', 'Banana', 'Cherry'],
}
return HttpResponse(template.render(context, request))
現在,指向詳情頁的連結就可以使用新的 slug 化 URL 了。
如果您已經在自己的計算機上完成了所有步驟,您可以在自己的瀏覽器中看到結果: 127.0.0.1:8000/members/
。
如果伺服器已停止,您需要使用 runserver
命令重新啟動它。
py manage.py runserver