文章详情页
文章详情页中显示文章的所有详细信息
模板文件
之前下载的博客模板中,找到article.html
文件,将其复制到templates/blog/
目录中。
$ cp article.html ~/fbckf/templates/blog/
<!-- blog-content -->
<div class="container content">
<div class="row justify-content-center">
<div class="col-8">
<div class="blog-header">
<h1 class="blog-title"><strong>{{ article.title }}</strong></h1>
<p class="blog-post-meta ">January 1, 2018 by <a href="#">{{ article.author }}</a></p>
</div>
<div class="blog-post border-bottom">
{{ article.body | safe }}
<img src="{% static 'blog/img/3.jpg' %}" style="width: 100%;">
</div>
<!-- 判断用户是否登陆,没有登陆无法点赞和评论 -->
{% if username %}
<div class="center">
<button class="btn btn-outline-dark btn-lg" type="button" data-toggle="collapse" href="#post-comment" role="button" aria-expanded="false" aria-controls="post-comment">
<i class="fa fa-comment-o" aria-hidden="true"></i> 评论</button>
<button type="button" class="btn btn-lg btn-outline-danger" data-toggle="body" data-content="您是第 {{ article.likes }} 位喜欢这篇文章的读者!">
<i class="fa fa-heart-o" aria-hidden="true"></i> 喜欢
</button>
<div class="collapse" id="post-comment">
<form action="#">
<div class="form-group">
<textarea name="comment" id="input-comment" cols="30" rows="5" class="form-control"></textarea>
</div>
<button class="btn btn-outline-dark" type="submit">发送</button>
</form>
</div>
</div>
{% endif %}
<div class="comment-list">
<div class="comment-detail">
<div class="row justify-content-start">
<img src="{% static 'blog/img/carousel2.jpg' %}" class="rounded" alt="user" style="width: 50px; height: 50px;">
<p class="lead col"> fbckf</p>
</div>
<div class="row justify-content-end">
<p class="col-11">Lorem ipsum dolor sit amet, consectetur adipisicing elit. Cupiditate velit, nam quo eveniet repellendus numquam, labore, fugit incidunt dicta enim perspiciatis et ab. Provident maiores non suscipit earum explicabo dolorum?</p>
</div>
<div class="row justify-content-end">
<ul class="list-group list-group-flush col-11" >
<li class="list-group-item">
<div class="row justify-content-start">
<img src="{% static 'blog/img/carousel2.jpg' %}" class="rounded" alt="user" style="width: 50px; height: 50px;">
<p class="lead col"> fbckf</p>
</div>
<div class="row justify-content-end">
<p class="col-11">Lorem ipsum dolor sit amet, consectetur adipisicing elit. Cupiditate velit, nam quo eveniet repellendus numquam, labore, fugit incidunt dicta enim perspiciatis et ab. Provident maiores non suscipit earum explicabo dolorum?</p>
</div>
</li>
</ul>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
以上和之前修改首页模板时差不多,不过要注意的一点是 {{ article.body | safe }}
标签中的 safe
。django会将文章内容强制转义,所以有时会造成一些麻烦,加上 safe
表示该内容安全,不需要转义。
添加 url 规则
# blog/urls.py
from django.urls import path
from . import views
app_name = 'blog'
urlpatterns = [
path('', views.index, name='index'),
path('search/', views.search , name='search'),
# 添加文章详情页 url 规则
path('article/<slug>/', views.article, name='article'),
]
path()
中的第一个参数与之前又有不同,'<slug>'
中表示的是字符,在点击文章的Read more
按钮后会访问 127.0.0.1:8000/article/[文章名]/
这个 url, 之后会将文章名保存变量 slug
中。具体的可以查看官方文档。
添加视图函数
# blog/views.py
...
def article(request, slug):
context = {}
# 根据 slug 的值获取文章
article = Article.objects.get(title=slug)
context['article'] = article
if request.user.is_authenticated:
context['username']= request.user.username
return render(request, 'blog/article.html', context=context)
要注意一点,这里是使用文章的 title
字段来获取文章,所以模型的 title
字段必须具有唯一性,比如之前设在的 unique-True
。
完成之后,在首页点击文章的 Read more
按钮就会跳转到那篇文章的详情页中。
点赞功能
当用户点击喜欢按钮后,会弹出 “对话气泡” 框,里面提示喜欢人数
添加视图函数
每次点击时,文章的 likes
字段值加一
# blog/views.py
def like_article(request):
article_title = None
# 判断是否时 get 模式
if request.method == "GET":
article_title = request.GET['article_title']
article = Article.objects.get(title=article_title)
# 获取到文章对象后,更新 likes 字段的值
if article:
article.likes = article.likes + 1
article.save()
return HttpResponse(article.likes)
添加 url 规则
from django.urls import path
from . import views
app_name = 'blog'
urlpatterns = [
path('', views.index, name='index'),
path('search/', views.search , name='search'),
path('article/<slug>/', views.article, name='article'),
path('like_article/', views.like_article, name='like_article'),
]
修改模板文件
...
<button id="like_article" value="{{ article.title }}" type="button" class="btn btn-lg btn-outline-danger" data-toggle="body" data-content="您是第 {{ article.likes|add:1 }} 位喜欢这篇文章的读者!">
<i class="fa fa-heart-o" aria-hidden="true"></i> 喜欢
</button>
...
给
<button>
标签添加一个id
和value
属性id
属性是为了后面写 ajax 准备的value
的值是文章的标题,ajax 将其传递到服务器{{ article.likes|add:1 }}
点击之后显示原likes
的值加一,之后后台进行更新
ajax
点击按钮之后,通过使用 ajax 来异步访问 url 进行更新字段值。
...
$("#like_article").click(function(){
var article_title = $(this).attr("value");
$.get('/like_article/', {article_title:article_title}, function(data){
$("#like_article").attr('disabled', true);
});
});
...
$.get()
方法第一个参数为 url 第二个参数是传递数据 第三个是函数,收到返回结果之后执行的内容传递的数据会以
get
模式传递到后台点击后给按钮添加 disabled 属性 防止用户连续点击
每次打开文章页面之后,如果登陆了账户,则可以个文章点赞,但是每个用户只能点击一次。
总结
文章页的功能还没有全部完成,包括 markdown 语法和评论功能