上篇我们引入了Bootstrap,对博文列表页面进行了一些美化和布局设计。
本篇我们来实现博客的另外一个核心功能:文章详情查看,同时在在导航抬头增加相关入口。
我们需要展示博文详情,首先就需要实现一个从数据库中获取文章相关数据的视图函数。
打开article/views.py,增加文章详情页面的视图函数article_detail():
- # 文章详情
- def article_detail(request, id):
- # 取出相应的文章
- article = Article.objects.get(id=id)
- # 需要传递给模板的对象
- context = { 'article': article }
- # 载入模板,并返回context对象
- return render(request, 'article/detail.html', context)
article_detail(request, id)函数中多了id这个参数。有了它才有办法知道到底应该取出哪篇文章。Article.objects.get(id=id)意思是在所有文章中,取出id值相符合的唯一的一篇文章。然后编写django4blog/urls.py,配置路由地址:
- urlpatterns = [
- path('admin/', admin.site.urls),
- path('hello/', views.hello),
- path('article/', views.article_list), # 展示文章
- # 添加此项
- path('article-detail/
/' , views.article_detail), # 文章详情 - ]
:Django用尖括号<>定义需要传递的参数。这里需要传递名叫id的整数到视图函数中去。
在templates/article中新建detail.html文件,编写如下代码:
- {% extends "base.html" %}
- {% load static %}
-
- {% block title %}
- 文章详情
- {% endblock title %}
-
- {% block content %}
-
-
- <div class="container">
-
-
- <h1 class="col-12 mt-4 mb-4">{{ article.title }}h1>
- <div class="col-12 alert alert-primary">
- <div class="col-12">
- <a>作者:{{ article.author }}a>
-  
- <a>{{ article.created|date:'Y-m-d H:i:s' }}a>
- div>
- div>
- {# <br>#}
-
- <div class="col-12">
- <p>{{ article.body }}p>
- div>
-
- div>
-
- {% endblock content %}
这里我们用{{ article.xxx }}取出了文章标题、创建时间,作者以及正文。
前面我们已经通过后台创建了几篇文章,这里将取出id为1的一篇文章测试效果。
运行开发服务器后,在浏览器中输入http://127.0.0.1:8000/detail/1/:

一般情况下我们查看文章详情不会直接输入地址来查看,而是通过文章列表页,点击特定按钮跳转到网页详情页。
所以接下来我们修改下文章列表页面增加一些链接跳转。
这里我们增加两个跳转链接:
1、点击导航栏首页跳转到文章列表页
打开templates/header.html
- <nav class="navbar navbar-expand-lg navbar-dark bg-dark">
- <div class="container">
-
-
- <a class="navbar-brand" href="#">我的博客a>
-
-
- <div>
- <ul class="navbar-nav">
- <li class="nav-item">
-
- <a class="nav-link" href="{% url 'list' %}">首页a>
- li>
- ul>
- div>
-
- div>
- nav>
刷新我们网址:http://127.0.0.1:8000/list/ ,发现报错了。

原因是我们在模板增加了 href地址 {% url 'list' %},这个链接里面对应的url 名字list无法反向解析到地址。
打开django4blog/urls.py,修改文章列表的path函数,增加name参数:'list'。
- urlpatterns = [
- path('admin/', admin.site.urls),
- path('hello/', views.hello),
- re_path(r'^$', views.article_list),
- # 修改此项,增加name参数
- path('list/', views.article_list, name='list'), # 文章列表
- # 文章详情
- path('detail/
/' , views.article_detail), - ]
刷新网页后,可以正常显示了。

{% url '...' %}是Django规定的模板解耦语法,用它可以根据我们在urls.py中设置的名字,反向解析到对应的url中去。实际上我们也可以直接在href中写入url的地址:href="/list",但是一旦url有变化,所有相关的链接都会失效,维护性不好。
使用名字的话,只要对应url的名字不变,url本身地址无论怎么变化,Django都可以解析到正确的地址,很灵活。
2、让用户可点击阅读本文按钮进入文章详情:
和上面一样,我们先给url地址命名,打开django4blog/urls.py,修改文章详情的path函数,增加name参数:'detail'。
- urlpatterns = [
- path('admin/', admin.site.urls),
- path('hello/', views.hello),
- re_path(r'^$', views.article_list),
- path('list/', views.article_list, name='list'), # 展示文章
- # 修改此项,增加name参数
- path('detail/
/' , views.article_detail, name='detail'), # 文章详情 - ]
然后打开list.html,修改href链接代码如下:
-
- <div class="card-body">
- <h4 class="card-title">{{ article.title }}h4>
- <br>
- <p class="card-text">{{ article.body|slice:'100' }}...p>
-
- <a href="{% url 'detail' article.id %}" class="card-link">阅读本文a>
- div>
这个链接href 里面除了 url 名字外,还多了article.id,我们看下这个id是如何在url和视图函数中间传递,并最终获取到数据库中的数据的。
list.html中,通过href="{% url 'detail' article.id %}",将id传递给urls.pyurls.py中,通过传递给视图函数article_detail()article_detail()中,通过形参id取得了文章的id值,并进行处理,最终定位了需要获取的文章对象。本篇我们实现了文章详情的页面,同时通过修改模板里面的href 链接,我们增加了导航栏对首页的跳转和首页中跳转文章详情的入口。
在修改href的时候,我们熟悉了path函数中的name参数,通过模板标签 {% url %},我们可以通过url名字反向解析url地址,增加了url配置的灵活性。
下篇我们将学习Django的Form,同时利用Form,实现创建文章的功能页面。