本文涉及的样例代码已经同步更新到HelloGitHub-Team仓库[1]。在此之前,我们已经编写了博客的主页视图,并配置了URL和模板,以便django能够正确处理HTTP请求并返回适当的HTTP响应。然而我们只是在首页回了一句:“欢迎来到我的博客”,这是一个Hello世界级的查看功能,毫无美感。
在本文中,我们需要编写一个真正的主页视图功能。当用户访问我们的博客主页时,会看到我们发布的博客文章列表,如演示项目所示[2]。
首页视图函数
在上一节中,我们解释了django的开发过程。也就是先配置好URL,将URL绑定到相应的视图函数,一般写在urls.py文件中,然后导入到项目的urls.py文件中。其次,编写视图函数,需要在视图中渲染模板。我们还在settings.py中配置了模板,这样django就可以找到需要渲染的模板。最后,只需返回呈现的HTTP响应。之前已经完成了相关的配置和准备工作。这里我们只需要专心写视图函数,让它实现我们想要的功能。
首页的视图功能其实很简单,代码是这样的:
blog/views . py from django . shortcut s导入renderfrom。模型导入Postdef索引(请求):post_list = Post.objects.all()。order _ by(‘-created _ time ‘)Return render(request,’ blog/index.html ‘,context = { ‘ post _ list ‘:post _ list })我们已经在前一章解释了模型管理器对象的使用。这里我们使用all()方法从数据库中获取所有文章,并将它们存储在post_list变量中。all方法返回一个QuerySet(可以理解为类似于列表的数据结构)。一般来说,博客文章列表是按照文章的发表时间逆序排列的,即最新的文章排在最前面,所以我们马上调用order_by方法对返回的queryset进行排序。排序依据的字段是created_time,即文章的创建时间。-号表示逆序,如果不加-号就是正序。然后,像前面一样,我们呈现blog\index.html模板文件,并将包含文章列表数据的post_list变量传递给模板。
处理静态文件
我们的项目使用了一套从互联网上下载的博客模板(点击这里下载全套模板[3])。除了HTML文档,还有一些CSS文件和JaScript文件,让网页呈现出我们现在看到的风格。同样,我们需要为django做一些必要的配置,让django知道如何将这些CSS和JaScript文件引入开发服务器,这样博客页面的CSS样式才能生效。
传统上,我们将CSS和JaScript文件放在博客应用程序的static\目录中。所以,先在博客应用下设置一个静态文件夹。同时,为了避免与其他应用中的css和JaScript文件发生命名冲突(其他应用也可能有与博客应用同名的CSS和JaScript文件),我们会在static\目录下创建一个博客文件夹,将下载的博客模板中的CSS和js文件夹连同其中的所有文件复制到这个目录下。最后,我们的博客应用程序目录结构应该是这样的:
博客\ _ _ init _ _。pystatic \ blog \ CSS \。CSS文件…js文件…管理员。pyapps。pymigrations \ _ _ init _。模特们。pytests。pyviews.py用下载的博客模板中的index.html文件替换我们之前写的index.html文件。如果您很好奇,现在可以运行开发服务器,看看主页是什么样子的。
如图,你会看到首页显示的样式非常混乱,因为浏览器无法正确加载CSS等样式文件。需要用django的方式正确处理CSS、JaScript等静态文件的加载路径。CSS样式文件通常在HTML文档的head标签中引入。打开index.html文件,找到文件开头的head标记中包含的内容,如下所示:
templates/blog/index.html <!DOCTYPE html & gt& lthtml & gt& lthead & gt& lttitle & gt黑色& amp白色& lt/title & gt;& lt!-meta-& gt;& ltmeta charset=”UTF-8 ” >& ltmeta name = ” viewport ” content = ” width = device-width,initial-scale=1 ” >& lt!-CSS-& gt;& ltlink rel = ” style sheet ” href = ” CSS/bootstrap . min . CSS ” & gt;& ltlink rel = ” style sheet ” href = ” http://code . ionicframework . com/io icons/2 . 0 . 1/CSS/io icons . min . CSS ” & gt;& ltlink rel = ” style sheet ” href = ” CSS/pace . CSS ” & gt;& ltlink rel = ” style sheet ” href = ” CSS/custom . CSS ” & gt;& lt!-js-& gt;& ltscript src = ” js/jquery-2 . 1 . 3 . min . js ” & gt;& lt/script & gt;& ltscript src = ” js/bootstrap . min . js ” & gt;& lt/script & gt;& ltscript src = ” js/pace . min . js ” & gt;& lt/script & gt;& ltscript src = ” js/modernizr . custom . js ” & gt;& lt/script & gt;& lt/head & gt;& ltbody & gt& lt!-其他内容-& gt;& ltscript src = ” js/script . js ” & gt;& lt/script & gt;& lt/body & gt;& lt/html & gt;CSS样式文件的路径在link标签的href属性中,JaScript文件的路径在Script标签的src属性中。可以看到’ href = “CSS/bootstrap.min.css “或者src=”js/jquery-2.1.3.min.js “这样的引用。由于引用文件的路径错误,浏览器无法导入这些文件。我们需要改变他们,使他们走上正确的道路。将代码更改为以下内容,并在静态文件下正确引入CSS和JaScript文件:
templates/博客/index . html+{ % load static % } & lt;!DOCTYPE html & gt& lthtml & gt& lthead & gt& lttitle & gt黑色& amp白色& lt/title & gt;& lt!-meta-& gt;& ltmeta charset=”UTF-8 ” >& ltmeta name = ” viewport ” content = ” width = device-width,initial-scale=1 ” >& lt!-CSS-& gt;-& lt;link rel = ” style sheet ” href = ” CSS/bootstrap . min . CSS ” & gt;& ltlink rel = ” style sheet ” href = ” http://code . ionicframework . com/io icons/2 . 0 . 1/CSS/io icons . min . CSS ” & gt;-& lt;link rel = ” style sheet ” href = ” CSS/pace . CSS ” & gt;-& lt;link rel = ” style sheet ” href = ” CSS/custom . CSS ” & gt;+& lt;link rel = ” style sheet ” href = ” { % static ‘ blog/CSS/bootstrap . min . CSS ‘ % } ” & gt;+& lt;link rel = ” style sheet ” href = ” { % static ‘ blog/CSS/pace . CSS ‘ % } ” & gt;+& lt;link rel = ” style sheet ” href = ” { % static ‘ blog/CSS/custom . CSS ‘ % } ” & gt;& lt!-js-& gt;-& lt;script src = ” js/jquery-2 . 1 . 3 . min . js ” & gt;& lt/script & gt;-& lt;script src = ” js/bootstrap . min . js ” & gt;& lt/script & gt;-& lt;script src = ” js/pace . min . js ” & gt;& lt/script & gt;-& lt;script src = ” js/modernizr . custom . js ” & gt;& lt/script & gt;+& lt;script src = ” { % static ‘ blog/js/jquery-2 . 1 . 3 . min . js ‘ % } ” & gt;& lt/script & gt;+& lt;script src = ” { % static ‘ blog/js/bootstrap . min . js ‘ % } ” & gt;& lt/script & gt;+& lt;script src = ” { % static ‘ blog/js/pace . min . js ‘ % } ” & gt;& lt/script & gt;+& lt;script src = ” { % static ‘ blog/js/modernizr . custom . js ‘ % } ” & gt;& lt/script & gt;& lt/head & gt;& ltbody & gt& lt!-其他内容-& gt;-& lt;script src = ” js/script . js ‘ % } ” & gt;& lt/script & gt;+& lt;script src = ” { % static ‘ blog/js/script . js ‘ % } ” & gt;& lt/script & gt;& lt/body & gt;& lt/html & gt;这里-表示删除这一行,+表示添加这一行。仔细看看加了什么,不要错过。
我们把引用路径放在一个奇怪的符号里,比如:href = ” { % static ‘ blog/CSS/bootstrap . min . CSS“% }”。用{%%}包装的内容称为模板标签。我们之前说过,包裹在{{}}里面的叫做模板变量,它的作用是在最终渲染的模板中显示view函数传递的变量值。我们这里使用的template标签的作用类似于一个函数,比如这里的static template标签,它将下面的字符串‘CSS/bootstrap . min . CSS’转换成正确的文件导入路径。这样可以正确加载css和js文件,正常显示样式。
注意:
为了能在模板中使用 {% static %} 模板标签,别忘了在最顶部 {% load static %} 。static 模板标签位于 static模块中,只有通过 load 模板标签将该模块引入后,才能在模板中使用 {% static %} 标签。
替换完成后,您可以刷新页面并查看页面的源代码,以查看页面呈现后{% static %}模板标记被替换为什么值。例如,我们可以看到
& ltlink rel = ” style sheet ” href = ” { % static ‘ blog/CSS/pace . CSS ‘ % } ” & gt;这部分最终在浏览器中显示的是:
& ltlink rel = ” style sheet ” href = “/static/blog/CSS/pace . CSS ” >这是pace.css文件所在的路径,其他文件路径也进行了类似的替换。可以看出{% static %}标签的作用其实是给下面的字符串加上一个/static/前缀,比如{% static ‘blog/css/pace.css’ %}的最终渲染值是/STATIC/blog/CSS/pace . CSS ./STATIC/前缀是由settings.py文件中的STATIC_URL = ‘/static/’指定的。其实如果我们可以直接把引用路径写成/static/blog/css/pace.css,为什么还要用{% static %}标签呢?想想吧。目前URL的前缀是/static/。如果有一天,因为某种原因,我们需要把/static/改成/resource/。如果不使用静态模板标签直接写报价,那么可能需要换n个地方。如果使用静态模板标签,只需要在settings.py中改变一个地方,即把STATIC_URL = ‘/static/’改为STATIC_URL = ‘/resource/’。
提示
有时候按 F5 刷新后页面还是很乱,这可能是因为浏览器缓存了之前的结果。按 Shift + F5(有些浏览器可能是 Ctrl + F5)强制刷新浏览器页面即可。如果还是不行,重启一下开发服务器以及清除浏览器缓存。
注意有一个CSS文件的介绍。
& ltlink rel = ” style sheet ” href = ” http://code . ionicframework . com/io icons/2 . 0 . 1/CSS/io icons . min . CSS ” & gt;我们没有使用template标签,因为这里引用的文件是一个外部文件,而不是我们项目的static\blog\css\目录中的文件,所以不需要使用template标签。
静态文件导入正确后,样式显示正常。
修改模板
目前我们看到的只是模板中的一些预填数据,还得让它显示从数据库中获取的文章数据。让我们稍微修改一下模板:
在模板index.html中,您会发现一系列文章标签:
模板/博客/索引. html…& ltarticle class = ” post ” >…& lt/article & gt;& ltarticle class=”post post-2 ” >…& lt/article & gt;& ltarticle class = ” post ” >…& lt/article & gt;…这里包的内容显示了文章数据。我们将一个post_list变量传递给视图函数index中的模板,该模板包含来自数据库的文章列表数据。就像Python一样,我们可以在模板中循环这个列表,把文章一条一条循环出来,然后把文章的数据一条一条显示出来。要在模板中使用循环,需要使用上面提到的template标记,这次使用{% for %} template标记。删除index.html中多余的文章标签,只留下一个文章标签,然后编写下面的代码:
模板/博客/索引. html…{ % for post _ list % } & lt;article class = ” post post-{ { post . PK } } ” & gt;…& lt/article & gt;{ % empty % } & ltdiv class=”no-post ” >还没发表的文章!& lt/div & gt;{% endfor %}…您可以看到语法类似于Python的for循环,但是它被类似于{%%}的模板标记符号所包装。{% empty %}的作用是当post_list为空时,显示下面{% empty %}的内容,即数据库中没有文章。最后,我们使用{% endfor %}告诉django循环到此结束。
你可能不太明白模板里的post和post_list是什么。Post_list是一个QuerySet(类似于列表的数据结构),其中每一项都是之前在blog\models.py中定义的Post类的一个实例,每个实例对应数据库中每篇文章的记录。所以我们遍历post_list,每次遍历的结果都存储在post变量中。所以我们使用模板变量来显示post的属性值。比如这里的{{ post.pk }}(pk是primary key的缩写,即post对应数据库中记录的id值。虽然我们没有展示定义,但是django会自动为我们添加)。
现在我们可以通过循环体中的post变量访问单篇文章的数据。分析文章标签中的HTML内容,h1显示文章的标题。
& lth1 class=”entry-title ” >& lta href = ” single.html ” & gt适应性与响应性布局和最佳文本可读性& lt/a & gt;& lt/h1 & gt;我们用post的标题属性值替换标题。请注意将它包装在模板变量中,因为它最终会被实际的标题值替换。
& lth1 class=”entry-title ” >& lta href = ” single.html ” & gt{ { post.title } } & lt/a & gt;& lt/h1 & gt;以下五个span选项卡分别显示了类别、发表时间、作者、评论数和阅读量。
& ltdiv class=”entry-meta ” >& ltspan class=”post-category ” >& lta href = ” # ” & gtDjango博客教程
& ltdiv class=”entry-meta ” >& ltspan class=”post-category ” >& lta href = ” # ” & gt{ { post . category . name } } & lt;/a & gt;& lt/span>。& ltspan class=”post-date ” >& lta href = ” # ” & gt& lttime class = ” entry-date ” datetime = ” { { post . created _ time } } ” & gt;{ { post.created _ time } } & lt/time & gt;& lt/a & gt;& lt/span>。& ltspan class=”post-author ” >& lta href = ” # ” & gt{ { post.author } } & lt/a & gt;& lt/span>。& ltspan class=”comments-link ” >& lta href = ” # ” & gt4条评论
& ltdiv class = ” entry-content clear fix ” >& ltp & gt免费,中文,零基础,完整项目,基于django 1.10和Python 3.5最新版本。带你从零开始一步步开发自己的博客网站,帮助你以最快的速度掌握django的开发技巧…
& ltdiv class = ” entry-content clear fix ” >& ltp & gt{ { post . extract } } & lt;/p & gt;& ltdiv class = ” read-more cl-effect-14 ” >& lta href=”#” class=”more-link ” >继续阅读
参考
[1] HelloGitHub-Team仓库:https://github.com/hello github-Team/hello django-blog-tutorial。
[2]示范项目:https://hellodjango-blog-tutorial-demo.zmrenwu.com/
[3]点击此处下载全套模板:https://github.com/zmrenwu/django-blog-tutorial-templates.
免责声明:本站所有文章内容,图片,视频等均是来源于用户投稿和互联网及文摘转载整编而成,不代表本站观点,不承担相关法律责任。其著作权各归其原作者或其出版社所有。如发现本站有涉嫌抄袭侵权/违法违规的内容,侵犯到您的权益,请在线联系站长,一经查实,本站将立刻删除。