我们的Post模型有一个slug字段,我们之前已经设置好了。现在我们想在Django中配置基于slug的路由。为了设计一个应用程序的URL,我们学习了如何使用Python模块URLconf或URL配置。URLconfg使用Python代码在URL路径表达式和视图中定义的Python函数之间进行映射。一些路由路径是静态的,而一些是动态的。换句话说,我们可以使用URL中的变量数据来确定如何映射到一个特定的视图函数。我们已经看到了如何使用基于整数的ID路由,在本教程中,我们将看到如何改用基于字符串的蛞蝓。
蛞蝓定义
Post mdel使用*lug = models.SlugField()*定义了lug,下面是突出显示。我们的系统目前在数据库中有三个Post模型,每个模型都有一个slug与之相关。到目前为止,我们的弹头是 a-new-title, second-post,以及 third-post.
posts/models.py
from django.db import models
# Create your models here.
class Post(models.Model):
title = models.CharField(max_length=100)
slug = models.SlugField()
body = models.TextField()
date = models.DateTimeField(auto_now_add=True)
def __str__(self):
return self.title
def snippet(self):
return self.body[0:70]
为Slug捕获定义URL路径
Web应用程序响应Http请求并使用请求中的参数来决定如何路由。我们的目标是能够访问像http://localhost:8000/posts/a-new-title/, http://localhost:8000/posts/second-post/, and http://localhost:8000/posts/third-post/ 这样的链接,Django将路由到每个特定的Post细节视图。为了捕捉URL中的slug变量,我们可以在**path()**函数中使用slug:slug参数。这在下面的代码中得到了强调。
posts/urls.py
from django.urls import path
from . import views
urlpatterns = [
path('', views.post_list),
path('<slug:slug>/', views.post_detail, name='post_detail'),
]
在上面的代码中,需要注意的另一件重要事情是 **name**参数被设置为post_detail。这是一个命名的URL模式,或一个命名的路由。这使你有能力链接到名称,而不是硬编码的hrefs。我们稍后会看到它是如何工作的。
使用捕获的Slug
现在在views.py文件的post_detail()函数中,我们可以使用*post_detail(request, slug)接受从URL中捕获的slug。然后,我们使用Django ORM的Post.objects.get(slug=slug)*代码,用这个lug来查询数据库。最后,我们渲染post_detail.html模板,同时将持有查询结果的上下文变量传递给数据库。
posts/views.py
from django.shortcuts import render
from .models import Post
def post_list(request):
posts = Post.objects.all().order_by('date')
return render(request, 'posts/post_list.html', {'posts': posts})
def post_detail(request, slug):
post = Post.objects.get(slug=slug)
return render(request, 'posts/post_detail.html', {'post': post})
通过Slug进行链接
帖子列表页需要每个帖子通过slug链接到帖子详情页。我们在href属性中使用*{% url 'post_detail' post.slug %}*来指定。这段代码在这里被强调了。
post/templates/posts/post_list.html
{% extends "./layout/base.html" %}
{% load static %}
{% block content %}
{% for post in posts %}
<div class="card mb-4" style="width: 40rem">
<img src="{% static 'posts/images/'|add:post.slug|add:'.jpeg' %}" class="card-img-top">
<div class="card-body">
<h3 class="card-title">{{ post.title }}</h3>
<h6 class="card-subtitle mb-2 text-muted">{{ post.slug }}</h6>
<p class="card-text">{{ post.snippet }}...</p>
<a href="{% url 'post_detail' post.slug %}" class="btn btn-primary">Read More</a>
</div>
</div>
{% endfor %}
{% endblock content %}
现在我们有了使用slug的链接,就像我们在这里看到的那样。

使用帖子细节模板
所有的管道都已就位,现在我们要做的是提供一个post_detail.html模板,像这样。
posts/templates/posts/post_detail.html
{% extends "./layout/base.html" %}
{% load static %}
{% block content %}
<div class="card mb-4" style="width: 40rem">
<img src="{% static 'posts/images/'|add:post.slug|add:'.jpeg' %}" class="card-img-top">
<div class="card-body">
<h3 class="card-title">{{ post.title }}</h3>
<h6 class="card-subtitle mb-2 text-muted">{{ post.slug }}</h6>
<p class="card-text">{{ post.body }}</p>
</div>
</div>
{% endblock content %}



Django中基于Slug的路由总结
为了使Django中的URL漂亮,我们可以使用基于lug的路由。使用蛞蝓还能带来SEO方面的好处,因为搜索引擎对描述性蛞蝓的理解要比URL中的简单ID更好。在本教程中,我们学习了如何处理使用slug进行路由,查询数据库,以及渲染一个帖子详情页的模板。