Django如何将作者与标题作为Slug构建author-name/title-of-book格式URL?
没问题,这其实很容易实现,咱们一步步来搞定它:
实现步骤
1. 给模型添加Slug字段并自动生成值
首先得确保你的作者(Author)和书籍(Book)模型都有符合URL规范的slug字段,并且在保存数据时自动把名字/标题转换成slug格式。如果还没加的话,修改你的模型代码:
from django.db import models from django.utils.text import slugify from django.urls import reverse class Author(models.Model): name = models.CharField(max_length=200) # 新增slug字段,设置unique避免重复冲突 slug = models.SlugField(unique=True, blank=True) def save(self, *args, **kwargs): # 如果slug为空,自动用作者名生成符合URL的格式 if not self.slug: self.slug = slugify(self.name) super().save(*args, **kwargs) class Book(models.Model): title = models.CharField(max_length=200) author = models.ForeignKey(Author, on_delete=models.CASCADE) # 书籍的slug字段,同样设为唯一 slug = models.SlugField(unique=True, blank=True) def save(self, *args, **kwargs): if not self.slug: self.slug = slugify(self.title) super().save(*args, **kwargs)
2. 更新get_absolute_url方法
接下来修改Book模型的get_absolute_url方法,让它生成你想要的author-name/title-of-book格式的URL:
def get_absolute_url(self): return reverse( 'book-detail', # 这个名称要和后面urls.py里定义的视图名称一致 kwargs={ 'author_slug': self.author.slug, 'book_slug': self.slug } )
3. 配置URL路由
在你的app的urls.py里添加对应的路由规则,接收两个slug参数:
from django.urls import path from . import views urlpatterns = [ # 保留你原来的其他路由... path( '<slug:author_slug>/<slug:book_slug>/', views.book_detail, name='book-detail' # 这里的名称必须和get_absolute_url里的对应 ), ]
4. 修改详情视图函数
原来的视图可能是用主键(pk)查询书籍,现在要改成通过作者slug和书籍slug来精准匹配:
from django.shortcuts import get_object_or_404, render from .models import Book def book_detail(request, author_slug, book_slug): # 用author__slug关联查询,确保找到的是对应作者下的目标书籍 book = get_object_or_404(Book, author__slug=author_slug, slug=book_slug) return render(request, 'your_template_dir/book_detail.html', {'book': book})
额外小提示
- 如果你已经有现有数据,记得给已存在的作者和书籍批量生成slug值,可以通过Django Shell执行:
from your_app.models import Author, Book from django.utils.text import slugify # 批量生成作者slug for author in Author.objects.all(): author.slug = slugify(author.name) author.save() # 批量生成书籍slug for book in Book.objects.all(): book.slug = slugify(book.title) book.save() - 如果担心不同作者的书籍标题重复导致slug冲突,可以考虑在生成书籍slug时加入作者信息,比如
slugify(f"{self.author.name}-{self.title}"),不过这样URL会稍长,你可以根据需求选择。
内容的提问来源于stack exchange,提问作者xaos_xv
相关产品推荐
相关产品推荐

