[学习:Django搭建个人博客 6]编写文章详情页面

373 阅读2分钟

参考:Django搭建个人博客:编写文章详情页面

有了文章列表页面后,当然还需要详情页面。

编写视图函数

打开article/views.py,增加文章详情页面的视图函数article_detail()

def article_detail(request,id):
    #取出相应的文章
    article = ArticlePost.objects.get(pk=id)

    #需要传递给模板的对象
    context = {'article':article}

    #载入模板,并返回context对象
    return render(request,'article/detail.html',context)

·article_detail(request, id函数中多了id这个参数。注意我们在写model的时候并没有写叫做id的字段,这是Django自动生成的用于索引数据表的主键(Primary Key,即pk)。有了它才有办法知道到底应该取出哪篇文章。 ArticlePost.objects.get(id=id)意思是在所有文章中,取出id值相符合的唯一的一篇文章。

然后编写article/urls.py,配置路由地址:

article/urls.py

...

urlpatterns = [
	...
	
    # 文章详情
    path('article-detail/<int:id>/', views.article_detail, name='article_detail'),
]
  • 使用尖括号“捕获”这部分 URL,且以关键字参数的形式发送给视图函数。
  • 上述字符串的 :id 部分定义了将被用于区分匹配模式的变量名,而 int: 则是一个转换器决定了应该以什么变量类型匹配这部分的 URL 路径。
  • 比如上面的<int:id>捕获这一部分URL,并将捕获数据作为视图article_detail(request,id)中的id参数传递过去。

编写模板

templates/article/中新建detail.html文件,编写如下代码:

templates/article/detail.html

<!-- extends表明此页面继承自base.html文件 -->
{% extends 'base.html' %} {% load static %}

<!--写入base.html中定义的title-->
{% block title %} 文章详情 {% endblock title %}

<!--写入base.html中定义的content-->
{% block content %}

<!--文章详情-->
<div class = "container">
    <div class = "row">
        <!--标题及作者-->
        <h1 class = "col-12 mt-4 mb-4">{{ article.title }}</h1>
        <div class = "col-12 alert alert-success">作者: {{article.author}}</div>
        <!--文章正文-->
        <div class = "col-12"><p> {{article.body}} </p></div>
    </div>
</div>
{% endblock content %}

使用{{ article.xxx }}取出文章标题作者以及正文

运行开发服务器后,在浏览器中输入http://127.0.0.1:8000/article/article-detail/1/

image.png

优化网页入口

改写header.html,让用户可通过导航栏右侧的文章链接返回首页:

templates/header.html

...
<div>
    <ul class="navbar-nav">
        <li class="nav-item">
        
            <!-- 改写了这里的 href --> 
            <a class="nav-link" href="{% url 'article:article_list' %}">文章</a>
          
        </li>
    </ul>
</div>

...

去除模板中的硬编码 URL

  • href定义了链接跳转的地址
  • {% url '...' %}是Django规定的语法,用于指明具体地址。
  • 关于其中的'article:article_list'的解释:
    • 前面的article是在项目根目录的urls.py中定义的命名空间。
    • 后面的article_list是在app中的urls.py中定义的具体的路由地址

然后再改写list.html,让用户可点击阅读本文按钮进入文章详情:

templates/article/list.html

...

<div class="card-footer">

    <!-- 同样改写 href -->
    <a href="{% url 'article:article_detail' article.id %}" class="btn btn-primary">阅读本文</a>
    
</div>

...

id是如何在文章中传递的

  • list.html中,通过href="{% url 'article:article_detail' article.id %}",将id传递给article/urls.py
  • article/urls.py中,通过<int:id>传递给视图函数article_detail()
  • 在视图函数article_detail()中,通过形参id取得了文章的id值,并进行处理,最终定位了需要获取的文章对象。

现在可以通过链接访问网站上的不同页面了,而不需要手动输入url了。