已知小问题修正

在模型中指定排序

为了让文章(Post)按发布时间逆序排列,即最新发表的文章排在文章列表的最前面,我们对返回的文章列表进行了排序,即各个视图函数中都有类似于 Post.objects.all().order_by('-created_time') 这样的代码,这导致了很多重复。因为只要是返回的文章列表,基本都是逆序排列的,因此我们可以在 Post 模型中指定 Post 的自然排序方式。

Django 允许我们在 models.Model 的子类里定义一个 Meta 的内部类,这个内部类通过指定一些属性来规定这个类该有的一些特性,例如在这里我们要指定 Post 的排序方式。首先看到 Post 的代码:

blog/models.py

@python_2_unicode_compatible
class Post(models.Model):
    ...
    created_time = models.DateTimeField()
    ...

    def __str__(self):
        ...

    def get_absolute_url(self):
        ...

现在在 Post 类的内部定义一个 Meta 类,并指定排序属性:

blog/models.py

@python_2_unicode_compatible
class Post(models.Model):
    ...
    created_time = models.DateTimeField()
    ...

    def __str__(self):
        ...

    def get_absolute_url(self):
        ...

    class Meta:
        ordering = ['-created_time']

ordering 属性用来指定文章排序方式,['-created_time'] 指定了依据哪个属性的值进行排序,这里指定为按照文章发布时间排序,且负号表示逆序排列。列表中可以用多个项,比如 ordering = ['-created_time', 'title'] ,那么首先依据 created_time 排序,如果 created_time 相同,则再依据 title 排序。这样指定以后所有返回的文章列表都会自动按照 Meta 中指定的顺序排序,因此可以删掉视图函数中对文章列表中返回结果进行排序的代码了。

完善跳转链接

导航栏有一个 Black & White 的 Logo,我们希望点击它就能回到首页面,只修修改一下超链接即可。打开 base.html,修改 Logo 处的超链接:

<header id="site-header">
  <div class="row">
      <div class="logo">
        - <h1><a href="index.html"><b>Black</b> &amp; White</a></h1>
        + <h1><a href="{% url 'blog:index' %}"><b>Black</b> &amp; White</a></h1>
      </div>
  ...
  </div>
</header>

另外导航栏还有一个首页导航按钮,也希望点击它就能回到首页面,修改的任务作为练习交给你了。

当然还有一些跳转可以完善,比如文章标题下有分类、发布时间、作者、评论量、阅读量等信息,可以设置点击分类跳转到分类页面;点击评论量就跳转到文章详情页的评论处等,这些细节部分不涉及新知识,就当做练习交给你自己完成了。

显示正确的评论量

有两处地方显示的评论量,显示评论量的方法很简单。回顾一下我们是如何获取某篇 post 的下的评论列表的?我们使用的是 post.comment_set.all()all 方法返回该 post 关联的评论列表。此外模型管理器(comment_set 是一个特殊的模型管理器)还有一个 count 方法,返回的是数量,即 post 下有多少条评论,我们可以直接在模板中调用这个方法:{{ post.comment_set.count }}。将评论量替换成该模板变量就可以正确显示文章的评论数了。

结束了么

我们通过一个博客实战项目,了解了 Django 基本的开发技术。包括如何编写模型(Model)、如何编写视图函数(View)、如何使用 Django 内置的模板系统(Template)以及如何配置路由(URL),这四大模块是 Django 开发的核心所在,现在我们已经能够基本掌握这些模块的使用方法了。

但是,还没完...

Django 提供的不仅仅是这些,我们的博客也不仅仅只有这些功能。如何实现标签云效果?如何给博客提供 RSS 订阅服务?如果实现文章搜索?如果网站需要提供用户系统,如何实现用户的注册登录?如何部署到服务器上让他人通过公网访问?这些需求都可以利用 Django 提供的 API 来实现。

另外,Django 还有海量的第三方应用来提供更加丰富的功能。比如当他人评论了我的文章时,如何收到通知提醒?网站需要提供新浪微博、微信等社交账号的登录等等,这些都可以借助 Django 第三方应用快速完成,而我们自己只需要写很少量的代码就可以了。

所以,让我们再接再厉,进入到 Django 博客开发进阶教程,学习更多的 Django 开发技巧,为博客提供更多的功能吧!

总结

本章节的代码位于:Step13: fix some issues

如果遇到问题,请通过下面的方式寻求帮助。

  • 在下方评论区留言。
  • 将问题的详细描述通过邮件发送到 djangostudyteam@163.com,一般会在 24 小时内回复。
  • Pythonzhcn 社区的新手问答版块 发布帖子。

-- EOF --


31 条评论 / 15 人参与
Lance-Klx

请问博主,修改之后评论数还是出不来是为什么呢?

<span class="comments-link"><a href="{{ post.get_absolute_url }}#comment-area">{{ post.comment_set.count }} 评论</a></span>

追梦人物 [博主] Lance-Klx

原因极可能是你的代码中存在和教程不一样的地方,一些细微的差异导致的错误。


Lance-Klx 追梦人物 [博主]

真的是,谢谢博主,感谢你的教程,大赞


derek-zhang123

博主 ,  新版教程链接在这里:https://www.zmrenwu.com/post/2/   

这个点的还是这个教程,请问新链接地址是哪个?谢谢


追梦人物 [博主] derek-zhang123

这个就是新版教程的链接了呀,看侧边栏的目录就是全部教程内容。


四有_青年

博主你好,为什么我点击 “ Django 博客开发进阶教程” 进入的还是当前教程?


追梦人物 [博主] 四有_青年

新版教程链接在这里:https://www.zmrenwu.com/post/2/


derek-zhang123 四有_青年

Django 博客开发进阶教程  这个地址在哪里


想吃肉的小猫熊

你好,我按照您的教程来做了,但是无论怎么渲染首页,都是在当前网址上面加index.html。请问这是为什么?非常感谢!


想吃肉的小猫熊 想吃肉的小猫熊

Lyu Zizheng 想吃肉的小猫熊

我也是这样!你弄出来了吗?


Lyu Zizheng 想吃肉的小猫熊

我弄出来 blogs\urls.py 里面加 app_name = 'blog'

把 blogproject\urls.py 里面的 namespace= blog 删掉


-陈思煜
我在添加点击分类名能跳转到相应的分类时

在进入文章页面后会提示: raise NoReverseMatch(msg)
django.urls.exceptions.NoReverseMatch: Reverse for 'category' with arguments '('',)' not found. 1 pattern(s) tried: ['category/(?P[0-9]+)/$']
请问是什么情况

-陈思煜 -陈思煜
已经知道是怎么回事了,后面的category.pk没有前面的 for函数,所以获取不到了

Annihilater -陈思煜

求问具体解决步骤


Wisink Annihilater

拿走不谢:<span class="post-category"><a href="{% url 'blog:category' post.category.pk %}">{{ post.category }}</a></span>

欢迎访问我的个人博客:http://wisink.life,有问题交流


Annihilater Wisink

谢谢!!


YuHui Wisink

访问不到了, 你的博客


梦境迷离99
{% csrf_token %}是什么标签

追梦人物 [博主] 梦境迷离99
防 csrf 攻击的。具体细节可以不必了解,有兴趣的可以百度或者 google csrf 攻击。

木二Lin
修改后出现了Reverse for 'index' with arguments '()' and keyword arguments '{}' not found. 0 pattern(s) tried: []这个问题,怎么办呢,搞了好久都没搞好

追梦人物 [博主] 木二Lin
需要看看和 index 视图有关的代码:url 配置、模板代码才能定位问题。当然最佳的解决方式是仔细对比和示例项目中的不同之处从而发现问题。

木二Lin 追梦人物 [博主]
是这样的,我的应用叫BlogModel,html里写的就是

Black & White

,就会出现NoReverseMatch at /
Reverse for 'index' with arguments '()' and keyword arguments '{}' not found. 0 pattern(s) tried: [],这样好像是找不到index视图函数

然后我查了网上的解答,改成了

Black & White

,错误就变成这个了NoReverseMatch at /
Reverse for '' with arguments '()' and keyword arguments '{}' not found. 0 pattern(s) tried: [],然后我就不懂为什么了,代码其他都一样啊

木二Lin 追梦人物 [博主]
主要是之前的"{% url 'BlogModel:archives' date.year date.month %}"都能工作啊,现在这里出问题查了很久都没查出来了,都快放弃了

木二Lin 追梦人物 [博主]
我老觉得是参数的问题,index视图函数没有参数传递,只有个request,所以出问题

木二Lin 追梦人物 [博主]
终于找到问题了,建议楼主在这加上注意要在url(r'^admin/', admin.site.urls),
url(r'^$', views.index, name = 'index')中加上name = 'index'这句,要不然找不到视图处理函数

追梦人物 [博主] 木二Lin
建议加在 blog.urls.py 里。

rockfire
改blog/views.py中的post_list=Post.objects.all().order_by('-created_time')为post_list=Post.objects.all()

laizetian_
你好,我使用这个blog项目ZinniaBlog-master,添加日志时,下方的标签显示No matches found,tag我已经配置了,请问是我哪里忽略了吗,麻烦指教,谢谢。

追梦人物 [博主] laizetian_
该项目已经废弃了,要使用 ZinniaBlog 部署博客请使用 github 上 django-zinnia-blog 的官方代码。

Superb-x
非常感谢博主,这个教程大概是我看过最详细的中文教程了