改写视图函数
上一章我们感受了视图的工作流程。
为了让视图真正发挥作用,改写article/views.py
中的article_list
视图函数:
article/views.py
from django.shortcuts import render
# 导入数据模型ArticlePost
from .models import ArticlePost
def article_list(request):
# 取出所有博客文章
articles = ArticlePost.objects.all()
# 需要传递给模板(templates)的对象
context = { 'articles': articles }
# render函数:载入模板,并返回context对象
return render(request, 'article/list.html', context)
代码同样很直白,分析如下:
from .models import ArticlePost
从models.py
中导入ArticlePost
数据类ArticlePost.objects.all()
是数据类的方法,可以获得所有的对象(即博客文章),并传递给articles
变量context
定义了需要传递给模板的上下文,这里即articles
模板的概念马上就要讲。
最后返回了
render
函数。它的作用是结合模板和上下文,并返回渲染后的HttpResponse对象。通俗的讲就是把context的内容,加载进模板,并通过浏览器呈现。
render
的变量分解如下:
- request是固定的
request
对象,照着写就可以 article/list.html
定义了模板文件的位置、名称context
定义了需要传入模板文件的上下文
视图函数这样就写好了。
编写模板(template)
在前面的视图中我们定义了模板的位置在article/list.html
,因此在根目录下新建templates
文件夹,再新建article
文件夹,再新建list.html
文件,即:
my_blog
│ ...
├─article
│ ...
└─my_blog
│ ...
└─templates
└─ article
└─ list.html
细心的你肯定注意到了,之前的Django文件后缀都是.py
,代表Python文件;这里的模板文件后缀是.html
,这又是什么呢?
HTML是一种用于创建网页的标记语言。它被用来结构化信息,标注哪些文字是标题、哪些文字是正文等(当然不仅仅这点功能)。也可以简单理解为“给数据排版”的文件,跟你写文档用的Office Word一样一样的 。
在list.html
文件中写入:
templates/article/list.html
{% for article in articles %}
<p>{{ article.title }}</p>
{% endfor %}
Django通过模板来动态生成HTML,其中就包含描述动态内容的一些特殊语法:
{% for article in articles %}`:`articles`为视图函数的`context`传递过来的上下文,即所有文章的集合。`{% for %}`循坏表示依次取出`articles`中的元素,命名为`article`,并分别执行接下来操作。末尾用`{% endfor %}
告诉Django循环结束的位置。使用
.
符号来访问变量的属性。这里的article
为模型中的某一条文章;我们在前面的ArticlePost
中定义了文章的标题叫title
,因此这里可以用article.title
来访问文章的标题。<p>...</p>
即为html语言,中间包裹了一个段落的文字。
在上一章中已经定义好了urls.py
,因此不再需要改动了。
一切都很好,深吸一口气。保存所有文件,在浏览器中输入地址http://127.0.0.1:8000/article/article-list/
,得到以下错误:
似乎成功从来都不会很顺利。
错误分析
虽然出错了,好在Django提供了非常完善的错误处理系统,方便开发者快速找到Bug的蛛丝马迹。
第一行就醒目地提示:TemplateDoesNotExist,说明Django没有找到list.html
这个文件。仔细检查目录、文件的名称无误,没问题就往下继续看。
然后发现有这么两行:
...django\contrib\admin\templates\article\list.html (Source does not exist)
...django\contrib\auth\templates\article\list.html (Source does not exist)
似乎Django在这两个位置搜索(没有在刚创建的templates目录),没有发现需要的文件,然后返回了“未发现模板文件”的错误。
定位了问题的所在,接下来就是在如何“告诉”Django我的模板位置呢?
答案就在settings.py
中了,它保存了Django项目的各种初始配置。
打开并找到这一段,加入代码os.path.join(BASE_DIR, 'templates')
:
my_blog/settings.py
TEMPLATES = [
{
...
# 定义模板位置
'DIRS': [os.path.join(BASE_DIR, 'templates')],
...
},
]
这就是说模板文件在项目根目录的templates
文件夹中,去找找吧。
保存文件,重新启动服务器:
成功!
虽然简陋,但是已经走通了MTV(model、template、view)环路。
不要激动,精彩的还在后面。
三个工具
此节为 2019/6/1 新增
读者在开发中每天都会遇到各种各样的问题。
解决问题的方法很多,其中有三个工具非常的有效,着重提一下:
Django报错页面:就是上面出现的那个黄黄的报错页面啦。Django报错页面在大多数情况下都能准确的判断错误类型、错误抛出的位置、甚至是解决方案。读者千万不要觉得读这么多英文好麻烦啊,其实重点就那么几句话。
浏览器控制台:如果你用的浏览器是Chrome,那么打开控制台的快捷键是
Ctrl + Shift + i
。控制台里又有两个子页面很常用:Elements这里列出整个网页源码,可以在这里查看css样式的继承情况、容器的相互关系,甚至可以动态修改源码查看效果。Console类似运行Django的命令行。如果浏览器运行网页时遇到故障(比如404 未找到资源
、403 服务器通讯失败
、500 服务器内部错误
),都会在这里提示。以后还可以在JavaScript代码中用console.log()
指令将感兴趣的内容打印到Console中查看。非常非常有用。**print()**:很多读者在写纯Python代码时知道用
print()
来查找bug,到Django中反而不会了。其实Django也是一样的,在视图函数中写的print()
会打印到命令行中。
依靠这三个工具,基本上就能给出90%以上的错误信息了。接下来就是把错误的关键词放到Google、Bing这些地方去搜索答案了。
再强调一下敲代码要细心。我发现很多读者的bug都是源自于拼写、缺行漏行这种让人沮丧的错误。
总结
本章我们重写了视图,编写了简单的模板,和前面的模型成功关联起来。
下一章将学习编写一个漂亮的网页模板。
- 有疑问请在杜赛的个人网站留言,我会尽快回复。
- 或Email私信我:dusaiphoto@foxmail.com
- 项目完整代码:Django_blog_tutorial