文章目录
- 0.思路引导
- 1.设计文章详情页的 URL
- 2.获取文章的URL
- 3.编写 detail 视图函数
- 4.编写详情页模板
- 5.更改主页中跳转详情页的地址链接
- 6.模板继承--抽取base.html
- 7.模板继承--修改 index.html使其继承base.html
- 8.模板继承--修改detail.html使其继承base.html
- 9.结果展示
0.思路引导
情景:博客首页展示的是所有文章的列表,当用户看到感兴趣的文章时,点击文章的标题或者继续阅读的按钮,应该跳转到文章的详情页面来阅读文章的详细内容。
实现方式:首先配置 URL,即把相关的 URL 和视图函数绑定在一起,然后实现视图函数,编写模板并让视图函数渲染模板。
逻辑总结:
1)用户进入博客首页时,根据blog/urls.py中路由的地址,调用视图函数中views.py的index()函数,此步骤一方面从后端获取全部文章的数据(注意每篇文章都有一个pk,也即文章id),另一方面将数据返回到index.html并展示给用户;
2)用户点击对内容感兴趣的博客(点击文章标题或者“继续阅读”)时,调用models.py中的get_absolute_url()函数;
目的是返回用户点击文章的pk,推送给路由中‘blog:datail’指定的视图,即views.py中的detail()函数;
3)detail()函数根据文章的pk,从后台数据库中获取数据,将数据推送到detail.html并展示给用户。
1.设计文章详情页的 URL
文件位置:blog/urls.py
from django.urls import pathfrom . import viewsapp_name = 'blog'
urlpatterns = [path('', views.index, name='index'),path('posts/<int:pk>/', views.detail, name='detail'),
]
此外我们通过 app_name=‘blog’ 告诉 django 这个 urls.py 模块是属于 blog 应用的
2.获取文章的URL
文件位置:blog/models.py
from django.contrib.auth.models import User
from django.db import models
from django.urls import reverse
from django.utils import timezoneclass Post(models.Model):...def __str__(self):return self.title# 自定义 get_absolute_url 方法# 记得从 django.urls 中导入 reverse 函数def get_absolute_url(self):return reverse('blog:detail', kwargs={'pk': self.pk})
3.编写 detail 视图函数
文件位置:blog/views.py
from django.shortcuts import render, get_object_or_404
from .models import Postdef index(request):# ...def detail(request, pk):post = get_object_or_404(Post, pk=pk)return render(request, 'blog/detail.html', context={'post': post}
4.编写详情页模板
从下载的博客模板中,把 single.html 拷贝到 templates\blog 目录下(和 index.html 在同一级目录),然后改名为 detail.html
5.更改主页中跳转详情页的地址链接
文件位置:templates/blog/index.html
<article class="post post-{{ post.pk }}"><header class="entry-header"><h1 class="entry-title"><a href="{{ post.get_absolute_url }}">{{ post.title }}</a></h1>...</header><div class="entry-content clearfix">...<div class="read-more cl-effect-14"><a href="{{ post.get_absolute_url }}" class="more-link">继续阅读 <span class="meta-nav">→</span></a></div></div>
</article>
{% empty %}<div class="no-post">暂时还没有发布的文章!</div>
{% endfor %}
在这里更改两个位置,第一个是文章标题处:
<h1 class="entry-title"><a href="{{ post.get_absolute_url }}">{{ post.title }}</a>
</h1>
第二处修改的是继续阅读按钮的链接:
<a href="{{ post.get_absolute_url }}" class="more-link">继续阅读 <span class="meta-nav">→</span>
</a>
6.模板继承–抽取base.html
首先在 templates\ 目录下新建一个 base.html 文件,可以看到 index.html 文件和 detail.html 文件除了 main 标签包裹的部分不同外,其它地方都是相同的,我们可以把相同的部分抽取出来,放到 base.html 里;
把 index.html 的内容全部拷贝到 base.html 文件里,然后删掉 main 标签包裹的内容,替换成如下的内容:
...
<main class="col-md-8">{% block main %}{% endblock main %}
</main>
<aside class="col-md-4">{% block toc %}{% endblock toc %}...
</aside>
...
这里的 {% block main %}{% endblock main %} 是一个占位框,main 是我们给这个 block 取的名字。
同时我们也在 aside 标签下加了一个 {% block toc %}{% endblock toc %} 占位框,因为 detail.html 中 aside 标签下会多一个目录栏。
当 {% block toc %}{% endblock toc %} 中没有任何内容时,{% block toc %}{% endblock toc %} 在模板中不会显示。但当其中有内容是,模板就会显示 block 中的内容。
7.模板继承–修改 index.html使其继承base.html
在 index.html 里,我们在文件最顶部使用 {% extends ‘base.html’ %} 继承 base.html,这样就把 base.html 里的代码继承了过来,另外在 {% block main %}{% endblock main %} 包裹的地方填上 index 页面应该显示的内容:
文件位置:templates/blog/index.html
{% extends 'base.html' %}{% block main %}{% for post in post_list %}<article class="post post-1">...</article>{% empty %}<div class="no-post">暂时还没有发布的文章!</div>{% endfor %}<!-- 简单分页效果<div class="pagination-simple"><a href="#">上一页</a><span class="current">第 6 页 / 共 11 页</span><a href="#">下一页</a></div>--><div class="pagination">...</div>
{% endblock main %}
8.模板继承–修改detail.html使其继承base.html
在 {% block main %}{% endblock main %} 里填充 detail.html 页面应该显示的内容,以及在 {% block toc %}{% endblock toc %} 中填写 base.html 中没有的目录部分的内容。
文件位置:templates/blog/detail.html
{% extends 'base.html' %}{% block main %}<article class="post post-1">...</article><section class="comment-area">...</section>
{% endblock main %}
{% block toc %}<div class="widget widget-content"><h3 class="widget-title">文章目录</h3><ul><li><a href="#">教程特点</a></li><li><a href="#">谁适合这个教程</a></li><li><a href="#">在线预览</a></li><li><a href="#">资源列表</a></li><li><a href="#">获取帮助</a></li></ul></div>
{% endblock toc %}
并修改上述文件中, article 标签下的一些内容为模板变量,让其显示文章的实际数据:
<article class="post post-{{ post.pk }}"><header class="entry-header"><h1 class="entry-title">{{ post.title }}</h1><div class="entry-meta"><span class="post-category"><a href="#">{{ post.category.name }}</a></span><span class="post-date"><a href="#"><time class="entry-date"datetime="{{ post.created_time }}">{{ post.created_time }}</time></a></span><span class="post-author"><a href="#">{{ post.author }}</a></span><span class="comments-link"><a href="#">4 评论</a></span><span class="views-count"><a href="#">588 阅读</a></span></div></header><div class="entry-content clearfix">{{ post.body }}</div>
</article>
9.结果展示
再次从首页点击一篇文章的标题或者继续阅读按钮跳转到详情页面,可以看到效果如下: