Django 是 Python web框架,发音 [ˈdʒæŋɡo] ,翻译成中文叫“姜狗”。

为什么要学框架?其实我们自己完全可以用 Python 代码从0到1写一个web网站,但那样就要写网络服务、数据库读写等底层代码。而框架的作用是把这些底层基建已经搭建好了,我们只写业务逻辑即可。

举个例子,楼房就是框架,我们不关心底层的脚手架、钢筋水泥是如何搭建的,只要有了这样的框架我们就可以住进去,而里面的房间要怎么设计、装饰才是我们关心的。

1. 初识Django

我使用的 Python 版本是 3.8,先执行下面语句先安装 Django

pip install Django

安装完成后,执行下面语句创建 Django 项目

django-admin startproject duma

项目的名称可以自定义,我创建的项目名是 duma。

命令执行完毕后,在当前目录会生成 duma 目录,该目录包含以下源文件。

duma/
manage.py
duma/
__init__.py
settings.py
urls.py
asgi.py
wsgi.py

简单介绍下这几个文件的作用:

  • manage.py: 管理 Django 项目的命令行工具,就像一个工具箱,后面会经常用到
  • mysite/settings.py:Django 项目的配置文件,如:配置该项目使用什么数据库、包含哪些应用等
  • mysite/urls.py:Django 项目的 URL 声明
  • mysite/asgi.py:作为你的项目的运行在 ASGI 兼容的 Web 服务器上的入口。暂时用不到
  • mysite/wsgi.py:作为你的项目的运行在 WSGI 兼容的Web服务器上的入口。暂时用不到

后面的学习中,我们会使用、修改这上面的文件,那时候对他们的作用会有更深的体会。

运行下面命令,启动web服务,验证 duma 项目是否创建成功。

python manage.py runserver

执行命令,会看到有以下信息输出

Starting development server at http://127.0.0.1:8000/

在浏览器访问 http://127.0.0.1:8000/

看到上面的页面,说明项目创建成功。

接下来我们要在 duma 项目中创建一个应用(app)。一个项目里可以有多个应用,如电商项目里可以有商城应用、支付应用和会员应用等等。

执行这行命令,创建一个应用

python manage.py startapp ncov

这里创建了一个名为 ncov 的应用,用它来做一个疫情数据报告。项目根目录会发现有个 ncov 目录,包含以下文件

ncov/
__init__.py
admin.py
apps.py
migrations/
__init__.py
models.py
tests.py
views.py

先不介绍它们的作用,这些文件后面基本都会用到,到时候会详细介绍。

2. Hello, World

“Hello, World” 是学习任何编程语言的演示程序,现在我们用 Django 实现一个“Hello, World” web应用。

首先,在 “nocv/views.py” 文件中创建 index 函数

from django.http import HttpResponse

def index(request):
return HttpResponse('Hello, World!')

然后,在 ncov 目录中创建 urls.py 文件,它用来定义 ncov 应用包含的 url。如:在电商商城应用中,会有商城首页 url 和商品详情的 url。

在 urls.py 文件中添加一个url,使之与 index 函数对应起来。

from django.urls import path

from . import views

urlpatterns = [
path('', views.index, name='index'),
]

第一个参数是 url 的路径,这里是空字符串代表 ncov 应用的根路径;第二个参数是该 url 对应的视图;第三个参数是该 url 的名称,可自定义。

最后,在 “duma/urls.py” 添加代码,将 ncov 应用的 url 注册到 duma 项目中,添加后的代码如下

from django.contrib import admin
from django.urls import path, include urlpatterns = [
path('admin/', admin.site.urls),
path('ncov/', include('ncov.urls')), ]

在浏览器访问 ncov 应用根路径 http://127.0.0.1:8000/ncov/

如果看到如上图的页面就代表成功了。如果启动的服务关闭了,需要在 duma 目录执行 python manager.py runserver 命令重新启动web服务。

当访问 ncov 应用根路径的时候,浏览器会产生一个 http 请求,duma项目的web服务接到该请求后,根据 urls.py 中的配置,调用 “ncov/views.py” 文件的 index 函数来处理该请求,index 函数中用 HttpResponse 将字符串 “Hello, World” 构造为一个 http 响应结果并返回给浏览器,浏览器接到该响应结果后,在页面上显示 “Hello, World” 字符串。

细心的话,你会发现 HttpResponse('Hello, World!') 跟 print('Hello, World') 很像,后者是我们学习 Python 语言时第一个演示程序。它俩都是输出 “Hello, World” 字符串,前者输出在浏览器上,后者输出在控制台(命令行)上。

这就是框架的威力,我们只关注业务逻辑,底层的 http 如何请求、如何响应以及如何返回给浏览器都是框架帮我们做好了。

3. 连接数据库

一个电商网站会展现很多商品,这些商品信息都存储在数据库中。同样的,ncov应用也需要把疫情统计数据存储在数据库中。

打开 “duma/settings.py” 文件,找到 DATABASES配置,如下

DATABASES = {
'default': {
'ENGINE': 'django.db.backends.sqlite3',
'NAME': BASE_DIR / 'db.sqlite3',
}
}

这里有一些默认的配置。

“default.ENGINE”代表数据库引擎是 sqlite3,是一个轻量数据库。你也可以将数据库引擎改成 MySQL、MongoDB等。

“default.NAME”是数据库名称,对于sqlite数据库来说这里填数据库的路径, BASE_DIR 代表项目根目录,此时再看下项目根目录可以发现有 db.sqlite3文件,它是 Django 创建的,后面我们就用它来存储数据。

不知道你会不会有这样的疑问,说好的数据库,怎么是个文件?实际上数据库的底层就是文件,只不过是在文件之上建立了一套引擎可以将文件中的内容以表格展示,并提供增加、删除、修改、查找的功能。就好比程序员的本质也是人,只不过从事编程工作所以被称为程序员。

有了数据库,还需要在数据库里创建表。一般来说,可以用数据库命令直接建表。但由于我们用的是框架,所以就可以用 Django 来操作。

在 “ncov/models.py” 文件中创建一个 Django 模型

from django.db import models

class CyStat(models.Model):
stat_dt = models.CharField(max_length=10) # 日期
cy_name = models.CharField(max_length=50) # 国家名称
confirm = models.IntegerField() # 累计确诊
dead = models.IntegerField() # 累计死亡
heal = models.IntegerField() # 累计治愈
today_confirm = models.IntegerField() # 现有确诊
today_new_confirm = models.IntegerField() # 新增确诊

这里定义 CyStat 类用来表示每个国家每天的疫情统计数据。包括 7 个属性,用 models 中的类对象来初始化。

stat_dt 和 cy_name 定义为 models.CharField类型,代表字符类型。日期是 2021-11-01 这样的格式,占用10个字符,所以 max_length=10;对国家名称来说一般不超过 50 个字符,所以它的 max_length=50。

其他几个字段都是统计数字,用整型即可。

有了数据模型只是第一步,我们要怎么获取数据呢?这时候就需要将模型与数据库中的表关联起来。

首先,将 ncov 应用注册到 duma 项目里,在 “duma/settings.py” 文件中找到 INSTALLED_APPS 配置,并在数组中添加 ncov 应用,添加后 INSTALLED_APPS 数组如下

INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'ncov.apps.NcovConfig' # 注册 ncov 应用
]

接着,运行下面命令

python manage.py makemigrations ncov

执行后,可以看到输出以下信息

Migrations
for 'ncov':
ncov/migrations/0001_initial.py
- Create model CyStat

该命令会在 “ncov/migration” 目录下创建 0001_initial.py 文件,如果看源代码可能看不出它的功能,我们可以执行下面语句将其转成 sql 就容易理解了。

python manage.py sqlmigrate ncov 0001

执行后,输出

BEGIN;
--
-- Create model CyStat
--
CREATE TABLE "ncov_cystat" ("id" integer NOT NULL PRIMARY KEY AUTOINCREMENT, "stat_dt" varchar(10) NOT NULL, "cy_name" varchar(50) NOT NULL, "confirm" integer NOT NULL, "dead" integer NOT NULL, "heal" integer NOT NULL, "today_confirm" integer NOT NULL, "today_new_confirm" integer NOT NULL);
COMMIT;

可以发现实际上就是一条建表sql,表名是应用名和模型类名的组合,用下划线连接。除了 id 自动添加外,其他字段名称和定义与模型类属性一致。

最后,执行下面命令来完成建表操作

python manage.py migrate

我们可以打开 db.sqlite3 数据库来查看是否成功。Mac电脑自带 sqlite3 命令直接打开,Windows 电脑可以安装 SQLite Administrator客户端。

在项目根目录执行,打开数据库文件

sqlite3 db.sqlite3

执行 .tables 查看数据库中的表

sqlite> .tables
auth_group django_admin_log
auth_group_permissions django_content_type
auth_permission django_migrations
auth_user django_session
auth_user_groups ncov_cystat
auth_user_user_permissions

可以发现名为 ncov_cystat 的表,它就是按照 CyStat 类创建的表。除此之外还有很多其他表,它们是 Django 框架自带的,我们可以先忽略。

这样我们将模型 CyStat 类与数据库中的 ncov_cystat 表对应的,后续我们需要查询或者修改数据直接操作 CyStat 类就可以了,而不用写 sql。

这里我们又可以发现使用 Django 框架的一个优势 —— 将模型类与数据库隔离(行话叫解耦)。带来的好处是,如果未来我们的项目上线后想把 sqlite 数据库换成 MySQL,我们只需要在 settings.py 文件中修改 DATABASES 的数据库引擎和数据库名称,重新执行建表命令即可。表的定义以及对表的查询、更新逻辑完全不用改。

4. 编写web页面

最后一节,我们来编写web页面展现数据。有了上面的基础我们知道,应该在 views.py 文件中查询 ncov_cystat 表的数据,然后将数据返回给浏览器。

首先需要向 ncov_cystat 表中导入一些数据,可以参考之前的文章《用Python绘制全球疫情变化地图》自己抓取。

我也准备了一部分数据放在 “ncov/sql/插入疫情数据.sql” 源码包里,复制 1 ~ 60 行 sql 在 sqlite 客户端执行即可。

sqlite> insert into ncov_cystat(stat_dt, cy_name, confirm, dead, heal, today_confirm, today_new_confirm) VALUES ("2021-09-03", "cn", 123169, 5685, 115024, 2460, 33);
sqlite> insert into ncov_cystat(stat_dt, cy_name, confirm, dead, heal, today_confirm, today_new_confirm) VALUES ("2021-09-04", "cn", 123199, 5685, 115105, 2409, 30);
...

读取数据,返回给浏览器。修改 “ncov/views.py” 文件中的 index 函数

from django.shortcuts import render

from .models import CyStat

def index(request):
cy_stats = CyStat.objects.filter(cy_name='cn').order_by('-stat_dt')[:7]
context = {
'cy_stats': cy_stats
} return render(request, 'ncov/index.html', context)

CyStat.objects 会返回 ncov_cystat 表里所有记录,filter 用来按照字段过滤表中的数据,'cn'代表中国,cy_name='cn' 表示我们只保留国内数据,order_by 用来按照某字段(列)对返回的结果排序,字段名前加 ‘-’ 代表降序,这里我们只取最近 7 天的数据。

现在我们不能像 “Hello, World” 那样直接返回,因为那种方式返回的是一个字符串,没有任何样式。我们返回的应该是一个 HTML 文件,所以需要调用 reder 函数,返回 “ncov/index.html”。

在 ncov 目录里创建 “templates/ncov/index.html” 文件,编写以下代码

<h3>国内疫情数据</h3>

<table border="1">
<tr>
<td>日期</td>
<td>现有确诊</td>
<td>新增确诊</td>
</tr>
{% for stat in cy_stats %}
<tr>
<td> {{ stat.stat_dt }} </td>
<td> {{ stat.today_confirm }} </td>
<td> {{ stat.today_new_confirm }} </td>
</tr>
{% endfor %}
</table>

该文件中使用表格来展示数据,你会发现这并不是一个纯 HTML 文件。准确来说index.html 是Django 定义的一种模板语言,它支持按照一定的语法写 Python 代码,比如说里面的 for 循环、stat对象的使用。

render 函数可以执行解析模板语言,生成纯 HTML 文件,返回给浏览器。

在浏览器访问 http://127.0.0.1:8000/ncov/ ,可以看到如下页面

虽然数据能展示出来了,但有些丑,需要优化下前端样式。

刚刚说的 HTML 和 Django 模板语言都是标记语言,语法都比较简单,之前没学过的朋友可以找些教程简单补一下。

要展示比较漂亮的图片,一般要借助 js 实现,有 js 的基础的朋友可以自己写前端页面。如果没有可以用 pyecharts ,它支持用 Python 代码制作图表。

下载 pyecharts GitHub 项目(https://github.com/pyecharts/pyecharts)源码,将 “pyecharts/render/templates” 目录中的源文件复制到 “ncov/templates” 目录中,结果如下

继续修改 index 函数,改为使用 pyecharts API 返回折线图。

from django.http import HttpResponse
from django.shortcuts import render
from pyecharts.charts import Line, Map
from pyecharts import options as opts from .models import CyStat def index(request):
cy_stat = CyStat.objects.filter(cy_name='cn').order_by('-stat_dt')[:14] stat_list = [x.stat_dt for x in cy_stat]
stat_list.reverse() today_confirm_list = [x.today_confirm for x in cy_stat]
today_confirm_list.reverse() today_new_confirm_list = [x.today_new_confirm for x in cy_stat]
today_new_confirm_list.reverse() c = (
Line()
.add_xaxis(stat_list)
.add_yaxis("现有确诊", today_confirm_list)
.add_yaxis("新增确诊", today_new_confirm_list)
.set_global_opts(title_opts=opts.TitleOpts(title="国内疫情数据"))
)
return HttpResponse(c.render_embed())

页面效果如下

这样的效果才像点样。

学到这里,我们已经入门 Django 了,留个作业,看看你能否做出下面的效果。

全部代码(包括作业)关注公众号 渡码 回复 “django入门” 获取。今天介绍的只是 Django 一小部分内容,如果大家反馈较好后面会继续更新,有问题也可以随时提问。

小入门 Django(做个疫情数据报告)的更多相关文章

  1. 爬取疫情数据,以django+pyecharts实现数据可视化web网页

    在家呆着也是呆着,不如做点什么消磨时间呗~ 试试用django+pyecharts实现疫情数据可视化web页面 这里要爬疫情数据 来自丁香园.搜狗及百度的疫情实时动态展示页 先看看劳动成果: 导航栏: ...

  2. 张小龙在2017微信公开课PRO版讲了什么(附演讲实录和2016微信数据报告)

    今天2017微信公开课PRO版在广州亚运城综合体育馆举行,这次2017微信公开课大会以“下一站”为主题,而此次的微信公开课的看点大家可能就集中在腾讯公司高级副总裁.微信之父——张小龙的演讲上了!今天中 ...

  3. django 做 migrate 时 表已存在的处理方法

    django 做 migrate 时 表已存在的处理方法 文章来源:嗨学网 http://www.piaodoo.com 在开发web的时候,如果是以前已存在的项目,项目下载下来后,为了使用测试库的数 ...

  4. Jqgrid入门-结合Struts2+json实现数据展示(五)

    DEMO用的是ssh框架实现的,具体怎么搭建的就不多做说明了.分页表格的数据操作难点就是数据展现.至于增删改直接用hibernate原生的方法实现即可.         初步分析:表格要实现分页,那么 ...

  5. 用Django做一个省份选择器

    做一个省份选择器 使用django做后端, mysql数据库, jQuery 列出结构主要的文件, 其它配置比较简单 models.py 因为所有数据的结构基本一致, 把所有省份, 市和区全部存储一张 ...

  6. 17082 两个有序数序列中找第k小(优先做)

    17082 两个有序数序列中找第k小(优先做) 时间限制:1000MS  内存限制:65535K提交次数:0 通过次数:0 题型: 编程题   语言: G++;GCC;VC Description 已 ...

  7. Vue之小入门

    Vue之小入门 <div id="app">{{ greeting }}</div> <script> let oDiv = document. ...

  8. 开发 | 如何在微信小程序的页面间传递数据?

    我们在之前发布过小程序页面传值方法的简单介绍,说明了在小程序开发中,两种常见的页面之间传值方法. 本期,知晓程序(微信号 zxcx0101)为你带来的是「倒数记日」小程序开发者带来的,小程序开发中,有 ...

  9. 17082 两个有序数序列中找第k小(优先做) O(logn)

    17082 两个有序数序列中找第k小(优先做) 时间限制:1000MS  内存限制:65535K提交次数:0 通过次数:0 题型: 编程题   语言: G++;GCC;VC Description 已 ...

随机推荐

  1. windows 根据 端口号 找到进程ID PID

    List process by port number netstat -ano | findstr 8080 Proto Local Address Foreign Address State PI ...

  2. 华为云计算IE面试笔记-请描述华为容灾解决方案全景图,并解释双活数据中心需要从哪些角度着手考虑双活设计

    容灾全景图: 按照距离划分:分为本地容灾 同城容灾 异地容灾  本地容灾包括本地高可用和本地主备.(本数据中心的两机房.机柜) 本地高可用这个方案为了保持业务的连续性,从两个层面来考虑: ①一个是从主 ...

  3. 踩坑系列《九》 无法获取实体类xxx对应的表名

    话不多说,直接说明原因 类似于 @MapperScan(basePackages = "com.hyxiao.user.mapper") 启动类的mapper扫描注解的导入包正确的 ...

  4. requirejs的加载原理 - 场景1. 定义一个require依赖a模块

    我们学习一个新的技术,熟练的使用之后,就应该去探索它的原理.这篇文章我们来探索下requirejs的原理. 从4个场景来探索requirejs的原理 场景1. 定义一个require依赖b模块 场景2 ...

  5. JVM学习笔记——栈区

    栈区 Stack Area 栈是运行时的单位,堆是存储单位,栈解决程序的运行问题,即程序如何执行,如何处理数据. 每个线程在创建时都创建一个该线程私有的虚拟机栈,每个栈里有许多栈帧,一个栈帧对应一个 ...

  6. VulnHub 实战靶场Breach-1.0

    相比于CTF题目,Vulnhub的靶场更贴近于实际一些,而且更加综合考察了知识.在这里记录以下打这个靶场的过程和心得. 测试环境 Kali linux IP:192.168.110.128 Breac ...

  7. 微服务+异步工作流+ Serverless,Netflix 决定弃用稳定运行 7 年的旧平台

    作者 | Frank San Miguel 策划 | 田晓旭 2021 年,Netflix 会将大部分的工作负载从 Reloaded 转移到 Cosmos 平台.Cosmos 是一个计算平台,它将微服 ...

  8. 第29篇-调用Java主类的main()方法

    在第1篇中大概介绍过Java中主类方法main()的调用过程,这一篇介绍的详细一点,大概的调用过程如下图所示. 其中浅红色的函数由主线程执行,而另外的浅绿色部分由另外一个线程执行,这个线程最终也会负责 ...

  9. L1-027 出租 (20 分) java题解

    下面是新浪微博上曾经很火的一张图: 一时间网上一片求救声,急问这个怎么破.其实这段代码很简单,index数组就是arr数组的下标,index[0]=2 对应 arr[2]=1,index[1]=0 对 ...

  10. PAT (Basic Level) Practice (中文)1025 反转链表 (25分)

    1025 反转链表 (25分) 给定一个常数 K 以及一个单链表 L,请编写程序将 L 中每 K 个结点反转.例如:给定 L 为 1→2→3→4→5→6,K 为 3,则输出应该为 3→2→1→6→5→ ...