基于Django的Blog 5.改写视图函数

1.改写视图函数

# 导入 HTTPResponse 模块
from django.http import HttpResponse
from django.shortcuts import render

# 导入数据库中的ArticlePost
from .models import ArticlePost


# 视图函数
def article_list(request):
    # 获得所有博客文章的对象
    articles = ArticlePost.objects.all()
    # 需要传递给模板(templates)的对象
    context = { 'article': articles }
    # render函数: 载入模板, 并返回context对象
    return render(request, 'article/list.html', context)
  • 首先从当前目录中导入models.py中的ArticlePost类

  • ArticlePost.objects.all() 获得所有对象,并传递给Articles变量.有点类似于Flask中的xxx.query.filter_by(username=xxx).first()

  • context定义了需要传递给模板的上下文,在函数内定以后这里还要return出去

最后返回了render函数。它的作用是结合模板和上下文,并返回渲染后的HttpResponse对象。通俗的讲就是把context的内容,加载进模板,并通过浏览器呈现。

render的变量分解如下:

  • request是固定的request对象,照着写就可以
  • article/list.html定义了模板文件的位置、名称
  • context定义了需要传入模板文件的上下文

2.编写模板(template)

上一节我们定义了模板位置article/list.html 因此在根目录下新建templates文件夹,在新建article文件夹,在新建list.html

my_blog
│  ...
├─article
│  ...
└─my_blog
│  ...
└─templates
    └─ article
        └─ list.html

2.1 写入html

list.html文件中写入:

templates/article/list.html

{% for article in articles %}
    <p>{{ article.title }}</p>
{% endfor %}

这个跟flask里面的bootstrap语法差不多,

  • {% 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/,得到以下错误:

image-20200604132806241

3.错误分析

Django并没有识别我新建的文件夹中的template位置,因为Setting初始配置并没有更改

3.1 修改setting

my_blog/setting.py
TEMPLATES = [
    {
        'BACKEND': 'django.template.backends.django.DjangoTemplates',
      # 'DIRS': [],  修改前
        'DIRS': [os.path.join(BASE_DIR, 'templates')], # 修改后
        'APP_DIRS': True,
        'OPTIONS': {
            'context_processors': [
                'django.template.context_processors.debug',
                'django.template.context_processors.request',
                'django.contrib.auth.context_processors.auth',
                'django.contrib.messages.context_processors.messages',
            ],
        },
    },
]

# 

BASE_DIR 会找到当前文件夹的上一级(也就是my_blog的上一级my_blog,然后找到templates)

期间遇到bug 显示空白页面,发现原来是contenxt的字典索引写错乐 少了个s,导致html每次遍历articles都找不到articles所以显示空白

# 视图函数
def article_list(request):
    # 获得所有博客文章的对象
    articles = ArticlePost.objects.all()
    # 需要传递给模板(templates)的对象
    context = { 'article': articles }  # 少了个s
    # render函数: 载入模板, 并返回context对象
    return render(request, 'article/list.html', context)

image-20200604134234101

虽然简陋,但是已经走通了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都是源自于拼写、缺行漏行这种让人沮丧的错误。

posted on 2020-07-05 20:53  sunnywillow  阅读(42)  评论(0)    收藏  举报