Django 2.1.7 基于默认sqlite3 模型设计 以及 数据操做

上一篇章讲述了如何建立项目,本篇章主要讲解Django的模型设计。python

参考文献

Django 官网 2.1 文档mysql

通常操做数据库是经过写sql语句,那么能不能不写sql语句就能够操做数据库呢? 能够,就是经过接下来要给你们讲的ORM框架。redis

本篇章首先使用Django默认使用的sqlite3,后续再继续讲解使用mysql。sql

ORM框架

O是object,也就类对象的意思,R是relation,翻译成中文是关系,也就是关系数据库中数据表的意思,M是mapping,是映射的意思。在ORM框架中,它帮咱们把类和数据表进行了一个映射,可让咱们经过类和类对象就能操做它所对应的表格中的数据。ORM框架还有一个功能,它能够根据咱们设计的类自动帮咱们生成数据库中的表格,省去了咱们本身建表的过程。shell

django中内嵌了ORM框架,不须要直接面向数据库编程,而是定义模型类,经过模型类和对象完成数据表的增删改查操做。数据库

使用django进行数据库开发的步骤以下:django

  • 1.在models.py中定义模型类
  • 2.迁移
  • 3.经过类和对象完成数据增删改查操做

下面咱们以保存服务器资产信息为例来给你们介绍Django中进行数据库开发的整个流程。编程

1.定义模型类

模型类定义在models.py文件中,继承自models.Model类。bash

说明:不须要定义主键列,在生成时会自动添加,而且值为自动增加。服务器

设计服务器资产类

服务器类:

  • 类名:ServerInfo
  • 服务器名称:server_hostname
  • 服务器内网IP:server_intranet_ip
  • 服务器外网IP:server_internet_ip
  • 服务器上架日期:server_shelves_date

模型类的设计

根据设计,在models.py中定义模型类以下:

from django.db import models

class ServerInfo(models.Model):
    server_hostname = models.CharField(max_length=20, default=None)
    server_intranet_ip = models.CharField(max_length=20,default=None)
    server_internet_ip = models.CharField(max_length=20,default=None)
    server_shelves_date = models.DateField(auto_now_add=True)
复制代码

下一步就可使用Django自带的迁移的方式,建立数据库表。

2.激活模型

上面的一小段用于建立模型的代码给了 Django 不少信息,经过这些信息,Django 能够:

  • 为这个应用建立数据库 schema(生成 CREATE TABLE 语句)。
  • 建立能够与 ServerInfo 对象进行交互的 Python 数据库 API。
  • 可是首先得把 assetinfo 应用安装到咱们的项目里。

为了在咱们的工程中包含这个应用,咱们须要在配置类 INSTALLED_APPS 中添加设置。由于 AssetinfoConfig 类写在文件 assetinfo/apps.py中,因此它的点式路径是 'assetinfo.apps.AssetinfoConfig'。在文件 mysite/settings.py 中 INSTALLED_APPS 子项添加点式路径后,它看起来像这样:

不用死记硬背这个点路径,pycharm会自动提示。

3.迁移

如今你的 Django 项目会包含 assetinfo 应用。接着运行下面的命令:

$ python3 manage.py makemigrations assetinfo

看看生成的这个文件是什么样的,以下:

Django框架根据咱们设计的模型类生成了迁移文件,在迁移文件中咱们能够看到fields列表中每个元素跟Serverinfo类属性名以及属性的类型是一致的。同时咱们发现多了一个id项,这一项是Django框架帮咱们自动生成的,在建立表的时候id就会做为对应表的主键列,而且主键列自动增加。

执行迁移命令以下: python3 manage.py migrate

当执行迁移命令后,Django框架会读取迁移文件自动帮咱们在数据库中生成对应的表格。

迁移后目录结构以下图:

Django默认采用sqlite3数据库,上图中的db.sqlite3就是Django框架帮咱们自动生成的数据库文件。 sqlite3是一个很小的数据库,一般用在手机中,它跟mysql同样,咱们也能够经过sql语句来操做它。

使用navicat访问sqlite3数据库

从上图能够看到自动建立生成的表以及字段。

默认生成的表名称

细心的读者会发现上面生成的表的名字叫作assetinfo_serverinfo,assetinfo是应用的名字,serverinfo是模型类的名字。

数据表的默认名称为:

<app_name>_<model_name>
例:
assetinfo_serverinfo
复制代码

设计中间件类

中间件类:

类名:MiddlewareInfo 中间件名称:name 中间件端口号:port 中间件所属服务器:server 服务器-中间件的关系为一对多

打开assetinfo/models.py,定义中间件类代码以下:

# 中间件类:MiddlewareInfo
# 中间件名称: name
# 中间件端口号:port
# 中间件所属服务器:server
class MiddlewareInfo(models.Model):
    name = models.CharField(max_length=20)
    port = models.IntegerField()
    server = models.ForeignKey('ServerInfo')
复制代码

这里要说明的是,ServerInfo类和MiddlewareInfo类之间具备一对多的关系,这个一对多的关系应该定义在多的那个类,也就是MiddlewareInfo类中。

server = models.ForeignKey('ServerInfo')这句代码就让ServerInfo类和MiddlewareInfo类之间创建了一对多的关系。

在咱们以后迁移生成表的时候,Django框架就会自动帮咱们在图书表和英雄表之间创建一个外键关系。

生成迁移文件: python3 manage.py makemigrations assetinfo

执行以后,能够发现错误以下:

那么怎么解决这个错误呢?

解决model的外键错误

在外键值的后面加上 on_delete=models.CASCADE

能够看到错误提示,还须要设置一个默认值,那么下面就写多一个默认值,以下:

能够看到执行成功了。

中间类的代码以下:

class MiddlewareInfo(models.Model):
    name = models.CharField(max_length=20)
    port = models.IntegerField()
    server = models.ForeignKey('ServerInfo',on_delete=models.CASCADE, default=None)
复制代码

再查看一下生成的迁移文件,以下:

执行迁移的命令

python3 manage.py migrate

使用navicat查看表结构

注意上图中assetinfo_middlewareinfo表中有一列server_id,这一列名为何不叫server? server_id是根据MiddlewareInfo类的关系属性server生成的,对应着服务器表中的主键id。

4.数据操做

完成数据表的迁移以后,下面就能够经过进入项目的shell,进行简单的API操做。

进入项目shell的命令: python3 manage.py shell

由于我安装了ipython3,因此会自动进入ipython3的工具。

首先引入assetinfo/models中的类: from assetinfo.models import ServerInfo,MiddlewareInfo

查询全部服务器信息:

In [3]: ServerInfo.objects.all()
Out[3]: <QuerySet []>
复制代码

由于当前并无数据,因此返回空查询结果集。

新建服务器信息对象并写入一条数据:

In [7]: s = ServerInfo()

In [8]: s
Out[8]: <ServerInfo: ServerInfo object (None)>

In [9]: s.server_hostname = "test_server"

In [10]: s.server_intranet_ip = "172.168.0.1"

In [11]: s.server_internet_ip = "223.5.5.5"

In [12]: from datetime import date

In [13]: s.server_shelves_date = date(2019,6,4)

In [14]: s.save()

In [15]:
复制代码

再次查询全部服务器信息:

In [15]: ServerInfo.objects.all()
Out[15]: <QuerySet [<ServerInfo: ServerInfo object (1)>]>

In [16]: 

复制代码

查找服务器信息并查看值:

In [16]: server_info = ServerInfo.objects.get( id = 1 )

In [17]: server_info
Out[17]: <ServerInfo: ServerInfo object (1)>

In [18]: server_info.id
Out[18]: 1

In [19]: server_info.server_hostname
Out[19]: 'test_server'

In [20]: server_info.server_shelves_date
Out[20]: datetime.date(2019, 6, 4)

In [21]: server_info.server_intranet_ip
Out[21]: '172.168.0.1'

In [22]: server_info.server_internet_ip
Out[22]: '223.5.5.5'

复制代码

修改服务器信息:

In [23]: server_info.server_shelves_date = date(2018,6,4)

In [24]: server_info.save()

In [26]: server_info.server_shelves_date
Out[26]: datetime.date(2018, 6, 4)

In [27]: 

复制代码

从navicat查看以下:

删除服务器信息:

server_info.delete()

In [27]: server_info.delete()
Out[27]: (1, {'assetinfo.MiddlewareInfo': 0, 'assetinfo.ServerInfo': 1})

In [28]: ServerInfo.objects.all()
Out[28]: <QuerySet []>

In [29]: 
复制代码

对象的关联操做

建立一个ServerInfo对象,写入一条服务器信息:

In [29]: server1 = ServerInfo()

In [30]: server1.server_hostname = "redis_server"

In [32]: server1.server_intranet_ip = "172.168.0.1"

In [33]: server1.server_internet_ip = "223.5.5.5"

In [35]: server1.server_shelves_date = date(2019,6,4)

In [36]: server1.save()

复制代码

建立一个MiddlewareInfo对象,写入两条中间件信息:

In [39]: m1 = MiddlewareInfo()

In [40]: m1.name = "redis"

In [41]: m1.port = 6379

In [42]: m1.server = server1

In [43]: m1.save()

In [44]: m2 = MiddlewareInfo()

In [45]: m2.name = "memcached"

In [46]: m2.port = "26379"

In [47]: m2.server = server1

In [48]: m2.save()

In [49]: MiddlewareInfo.objects.all()
Out[49]: <QuerySet [<MiddlewareInfo: MiddlewareInfo object (1)>, <MiddlewareInfo: MiddlewareInfo object (2)>]>

复制代码

服务器与中间件是一对多的关系,django中提供了关联的操做方式。

得到关联集合:返回当前server1对象的全部中间件。

In [50]: server1.middlewareinfo_set.all()
Out[50]: <QuerySet [<MiddlewareInfo: MiddlewareInfo object (1)>, <MiddlewareInfo: MiddlewareInfo object (2)>]>

In [51]: 
复制代码

相关文章
相关标签/搜索