Django shell
输入一些数据后,就能过通过交互式终端会话以编程方式查看这些数据了。这种交互式环境称为 Django shell ,是测试项目和排除故障的有效方式。如下:
<...\Scripts> py.exe manage.py shell Python 3.8.3 (tags/v3.8.3:6f8c832, May 13 2020, 22:37:02) [MSC v.1924 64 bit (AMD64)] on win32 Type "help", "copyright", "credits" or "license" for more information. (InteractiveConsole) >>> from learning_logs.models import Topic >>> Topic.objects.all() <QuerySet [<Topic: Chess>, <Topic: Rock Climbing>]> >>> from learning_logs.models import Entry >>> Entry.objects.all() <QuerySet [<Entry: 据报道,伊朗国防部称,当地时间27日下午,武装恐怖分子袭击了一辆载有伊朗顶级核科学家穆赫森·法赫里扎...>, <Entry: 据武汉理工大学微信公众号27日晚间发布情况通报,近日,在武汉理工大学2020年通过博士、硕士研究生招...>]> >>>
还可以使用类似遍历列表的方式来查询集:
>>> topics = Topic.objects.all() >>> for topic in topics: ... print(topic.id, topic) ... 1 Chess 2 Rock Climbing >>> >>> t = Topic.objects.get(id=1) >>> t.text 'Chess' >>> t.date_added datetime.datetime(2020, 11, 27, 15, 22, 28, 573639, tzinfo=<UTC>) >>> t.entry_set.all() <QuerySet [<Entry: 据报道,伊朗国防部称,当地时间27日下午,武装恐怖分子袭击了一辆载有伊朗顶级核科学家穆赫森·法赫里扎...>]> >>>
创建网页:学习笔记主页
使用 Django 创建网页的过程通常分为三个阶段:
- 定义 URL
- 编写视图
- 编写模版
首先,必须先定义 URL 模式。URL 模式描述了 URL 是如何设计的,使得 Django 知道如何将浏览器请求与网站 URL 相匹配,以确定返回哪个网页。
每个 URL 都被映射到特定的视图——视图函数获取并处理网页所需的数据。视图函数通常调用一个模版,模版生成浏览器能够理解的网页。接下来,我们就来创建学习笔记的主页,定义该主页的 URL ,编写视图函数并创建一个简单的模版。
映射 URL
用户通过在浏览器中输入 URL 以及单击链接来请求网页,因此需要确定项目需要哪些 URL 。主页的 URL 最重要,是用户用来访问项目的基础 URL。当前,基础 URL(http://localhost:8000/)返回默认的 Django 网站,让我们知道正确地建立了项目。这里,将这个基础的 URL 映射到 “学习笔记” 的主页上。
打开项目主文件夹 learning_log 目录中的文件 urls.py ,内容如下:
"""learning_log URL Configuration The `urlpatterns` list routes URLs to views. For more information please see: https://docs.djangoproject.com/en/3.1/topics/http/urls/ Examples: Function views 1. Add an import: from my_app import views 2. Add a URL to urlpatterns: path('', views.home, name='home') Class-based views 1. Add an import: from other_app.views import Home 2. Add a URL to urlpatterns: path('', Home.as_view(), name='home') Including another URLconf 1. Import the include() function: from django.urls import include, path 2. Add a URL to urlpatterns: path('blog/', include('blog.urls')) """ from django.contrib import admin from django.urls import path urlpatterns = [ path('admin/', admin.site.urls), ]
内容的前两行导入了项目和管理网站的管理 URL 的函数和模块,内容主体定义了变量 urlpatterns 。在这个针对整个项目的 urls.py 文件中,变量 urlpatterns 包含项目中应用程序的 URL 。能够看到包含了模块 admin.site.urls ,这个模块定义了可以在管理网站中请求的所有 URL。这里可以添加需要包含 learning_logs 的 URL:
from django.contrib import admin from django.urls import path from django.urls import include urlpatterns = [ path('admin/', admin.site.urls), path('', include('learning_logs.urls')), ]
默认的 urls.py 文件在 learning_log 目录下,我们需要在目录 learning_logs 中创建另一个 urls.py 文件:
'''定义 learning_logs 的 URL 模式''' from django.conf.urls import url from django.urls import path from . import views urlpatterns = [ #主页 #url(r'^$', views.index, name='index'), path('', views.index, name='index'), ]
为了搞清楚当前位于哪个 urls.py 文件中,我们在文件开头添加了一个文档注释。这里导入了函数 url 和 views 模块,变量 urlpatterns 包含了可以在应用程序 learning_logs 中请求的网页。
实际的 URL 模式是一个对函数 url() 的调用,这个函数接收三个实参,
url(param1, param2, param3) # param1 正则表达式,匹配 urlpatterns 中查找和请求的 URL 字符串, # r'^$'中, # r 使得Python将接下来的字符串视为原始字符串,引号表示正则表达式开始和结尾, # `^`符号使得Python能够查看字符串的开头。 # '$'符号则能够使得Python查看字符串结尾。 # 综上所述, r'^$' 仅仅与 http://localhost:8000/ 这个 url 相匹配。 # param2 指定了要调用的视图函数,请求url 与前面的正则表示匹配的时候,Django 会调用 view.index 这个函数 # param3 将这个 URL 模式的名称指定为 index ,能够在代码的其他地方引用它,每当需要提供这个 url 链接时,只需要使用这个名称即可,不需要编写 URL。
编写视图
视图函数接收请求中的信息,准备好生成网页所需的数据,再将这些数据发送给浏览器——这通常是使用定义了网页的模版实现的。
learning_logs 中的文件 view.py 就是执行命令 python manage.py startapp 时自动生成的,当前内容如下:
from django.shortcuts import render # Create your views here.
当前,这个文件只导入了 render 函数,它根据视图提供的数据渲染响应,下面的代码演示了该如何为主页编写视图:
from django.shortcuts import render # Create your views here. def index(request): '''学习笔记的主页''' return render(request, 'learning_logs/index.html')
URL 请求与刚刚定义模式匹配后,Django 在文件 views.py 中查找对应函数 index() ,再将这个请求对象传递给视图函数。在这里,不需要处理任何数据,所以这个函数只需要包含 render() 调用代码,向函数 render() 提供两个实参:原始请求对象和可用于创建网页的模版。
编写模版
模版定义了网页的结构。模版指定了网页是什么样的,而每当网页被请求时,Django 将填入对应的数据。模版使得能够访问视图提供的任何数据。我们的主页视图没用提供任何数据,所以对应的模版非常简单。
在项目目录 learning_logs 中新建一个文件夹 templates ,在这个目录下新再新建一个 learning_logs 文件夹,这样能明确调用的模版是 learning_logs 应用对应的模版,后期如果需要添加其他的应用在这里继续添加对应的文件目录就可以了。在新建的 learning_logs 应用程序模版文件目录中新建一个模版文件 index.html ,添加内容如下:
<p>Learning Log</p> <p>Learning Log helps you keep track of your learning, for any topic you're learning about.</p>
这个内容很简单,标签
标识段落;标签
指出锻炼开头位置,
指出段落结束位置。
这时候再请求这个项目的基础 URL —— http://localhost:8000/ ,将看到以下内容:
创建其他网页
指定创建网页的流程后,就可以进行扩充 “学习笔记” 的项目了。接下来将创建两个显示数据的网页,其中一个列出所有的主题,另一个现实特定主题的所有条目。对于每个网页,都将指定 URL 模式,编写视图函数及模版。在这么做之前先创建一个父模版,项目中的其他模版都将继承它。
模版继承
创建网站时,几乎都有一些所有网页包含的元素,在这种情况下,可编写一个包含通用元素的父模版,并让每个网页都继承这个模版,而不必在每个网页中重复定义这些通用元素。这种方法能让你专注于开发每个网页的独特方面,还能让修改项目的整体外观容易很多。
- 父模版
首先创建一个名为 base.html 的模版,并将其存储到 index.html 的目录中,在这个文件中包含所有页面都有的元素,其他模版都会继承 base.html 。
当前,所有页面都包含的元素有顶端的标题,我们将在所有的页面中包含这个模版,因此将这个标题设置为到主页的链接:
注意:html中(模版文件)缩进层级是两个空格,不同于 Python 文件是四个空格。
base.html
<p> <a href="{% url 'learning_logs:index' %}">Learning Log</a> </p> {% block content %}{% endblock content %}
这个文件的第一部分创建一个包含项目名的段落,该段落是一个到主页的链接。为创建链接,需要使用模版标签(大括号和百分号表示)。模版标签是一小段代码,生成要在网页中显示的信息。<a href="{% url 'learning_logs:index' %}">Learning Log</a> ,生成 URL ,这个 URL 与 learning_logs/urls.py 中定义的 index URL 模式匹配。
后面紧接着插入一对块标签,这个块名为 content ,是一个占位符,其中包含的信息由子模版指定。子模版并非必须定义父模版中的每个块,所以在父模版中可以使用任意多个块来预留空间,子模版根据需要定义对应数量的块。
- 子模版
现在就需要重新改写 index.html 继承 base.html 进行使用,如下内容:
index.html
{% extends "learning_logs/base.html" %} {% block content %} <p>Learning Log helps you keep track of your learning, for any topic you're learning about.</p> {% endblock content %}
可以发现,在原来的基础上,原来的标题内容改成了从父模版继承,而正文内容则使用 content 的标签插入,在子模版中定义了 content 块。
显示所有主题的页面
有了高效的网页创建方法,就能专注于另外两个网页了:显示全部主题的网页以及显示特定主题中条目的网页。所有主题页面显示用户创建的所有主题,所以这是一个需要数据的网页。
- URL 模式
首先,我们来定义显示所有主题的页面的 URL。通常,使用一个简单的 URL 片段来指出网页提示的信息;使用单词 topics ,因此 URL http://localhost:8000/topics/ 将返回显示所有主题的页面。下面先修改 learning_logs/urls.py:
'''定义 learning_logs 的 URL 模式''' from django.conf.urls import url from django.urls import path from . import views urlpatterns = [ #主页 #url(r'^$', views.index, name='index'), path('', views.index, name='index'), path(r'^topics/$', views.topics, name='topics'), ]
在 urls.py 中添加了匹配 topics URL 的规则和调用的模型 views.topics。
- 函数 topics() 需要从数据库中获取一些数据,并将其发送给模版进行显示,修改 views.py 中的代码:
from django.shortcuts import render from .models import Topic # Create your views here. def index(request): '''学习笔记的主页''' return render(request, 'learning_logs/index.html') def topics(request): '''显示所有的主题''' topics = Topic.objects.order_by("date_added") context = {'topics':topics} return render(request, 'learning_logs/topics.html', context)
- 新建模版
显示所有主题的页面的模版接收字典参数 context ,以便能够使用 topics() 提供的数据。在 index.html 同级目录中创建新模版文件 topics.html ,具体如下:
{% extends "learning_logs/base.html" %} {% block content %} <p>Topics</p> <ul> {% for topic in topics %} <li>{{ topic }}</li> {% empty %} <li>No topics have been added yet.</li> {% endfor %} </ul> {% endblock content %}
其中用到的 for 循环格式类似如下:
{% for item in list %}
do something with each item
{% endfor %}
1
2
3
这里,还需要修改父模版,使其包含到显示所有主题的页面链接:
<p> <a href="{% url 'index' %}">Learning Log</a> <a href="{% url 'topics' %}">Topics</a> </p> {% block content %}{% endblock content %}
- 完成
都修改完成后,此时打开网页,访问 http://localhost:8000/topics/ 的 URL ,显示如下:
显示特定主题的页面
接下来,就需要创建一个专注于特定主题的页面——显示该主题的名称和所有条目。流程与之前相同。
- URL模式
在 learning_logs/urls.py 中添加内容,如下:
'''定义 learning_logs 的 URL 模式''' from django.conf.urls import url from django.urls import path from . import views urlpatterns = [ #主页 #url(r'^$', views.index, name='index'), path('', views.index, name='index'), path(r'^topics/$', views.topics, name='topics'), path(r'^topics/(?P<topic_id>\d+)/$', views.topic, name='topic'), ]
- 视图
添加对应的函数调用接口,在 learning_logs/views.py 中,如下:
from django.shortcuts import render from .models import Topic # Create your views here. def index(request): '''学习笔记的主页''' return render(request, 'learning_logs/index.html') def topics(request): '''显示所有的主题''' topics = Topic.objects.order_by("date_added") context = {'topics':topics} return render(request, 'learning_logs/topics.html', context) def topic(request, topic_id): '''显示单个主题的所有内容''' topic = Topic.objects.get(id=topic_id) entries = topic.entry_set.order_by("-date_added") context = {'topic' : topic, 'entries' : entries} return render(request, 'learning_logs/topic.html', context)
- 新建模版并修改 topics.html 模版,使得显示的所有主题名称改为链接
topics.html
{% extends "learning_logs/base.html" %} {% block content %} <p>Topics</p> <ul> {% for topic in topics %} <a href="{% url 'topic' topic.id %}">{{ topic }}</a> {% empty %} <li>No topics have been added yet.</li> {% endfor %} </ul> {% endblock content %}
topic.html
{% extends "learning_logs/base.html" %} {% block content %} <p>Topics</p> <p>Entries:</p> <ul> {% for entry in entries %} <li> <p>{{ entry.date_added|date:'M d, Y H:i' }}</p> <p>{{ entry.text|linebreaks }}</p> </li> {% empty %} <li> There are no entries for this topic yet. </li> {% endfor %} </ul> {% endblock content %}
- 完成
小结
在本篇内容中,简单学习了如何使用 Django 框架来创建 web 应用程序,并简单实现了 “学习笔记” 项目。在虚拟环境中安装了 Django ,创建项目并且能够在修改模型后轻松迁移数据库,方便项目的迁移部署。除此之外,还学习了 Django shell 的使用,能在终端通过 Django shell 来轻松查看调试网站的数据及接口调用。
通过本篇的基础,接下来就能够优化网页,实现更为复杂和完美的自定义网站了。