Django Slug 字段
什么是 Slug?
你见过这样的 URL 吗?
cainiaomax.com/django/learn-about-slug-field
"learn-about-slug-field"部分是网址别名(slug)。
网址别名仅包含字母、连字符、数字或下划线。
网址别名常用于网址中,使其更易于阅读,同时也有利于搜索引擎优化。
不带别名的网址
如果您按照本教程中的步骤创建了Django 项目,您将得到一个类似这样的小型 Django 项目:

如果您点击第一个成员,您将跳转到此页面:

请查看地址栏:
127.0.0.1:8000/members/details/1
数字"1"指的是数据库中该特定记录的 ID。
对于开发者来说这很合理,但对其他人来说可能就未必了。
带别名的 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 需要更新数据库。
python manage.py makemigrations
迁移命令:
python manage.py migrate
更改管理员
现在数据库中新增了一个字段,但我们希望在设置成员的名字或姓氏时,该字段也能自动更新。
这可以通过 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)
进入管理界面并打开一条记录进行编辑:

点击"保存",slug 字段将自动填充名字和姓氏。由于 slug 字段的类型为 SlugField,因此会对值进行"slugify"处理,即在每个单词之间添加连字符。
下次打开该成员进行编辑时,您将看到 slug 字段的值:

注意:由于新字段默认为空,因此您必须对每个成员执行此保存操作。
修改模板
现在我们可以在整个项目中将 ID 字段替换为 slug 字段。
首先使用 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 命令重新启动它:
python manage.py runserver

