上一篇章讲述了如何建立项目,本篇章主要讲解Django的模型设计。python
Django 官网 2.1 文档mysql
通常操做数据库是经过写sql语句,那么能不能不写sql语句就能够操做数据库呢? 能够,就是经过接下来要给你们讲的ORM框架。redis
本篇章首先使用Django默认使用的sqlite3,后续再继续讲解使用mysql。sql
O是object,也就类对象的意思,R是relation,翻译成中文是关系,也就是关系数据库中数据表的意思,M是mapping,是映射的意思。在ORM框架中,它帮咱们把类和数据表进行了一个映射,可让咱们经过类和类对象就能操做它所对应的表格中的数据。ORM框架还有一个功能,它能够根据咱们设计的类自动帮咱们生成数据库中的表格,省去了咱们本身建表的过程。shell
django中内嵌了ORM框架,不须要直接面向数据库编程,而是定义模型类,经过模型类和对象完成数据表的增删改查操做。数据库
使用django进行数据库开发的步骤以下:django
下面咱们以保存服务器资产信息为例来给你们介绍Django中进行数据库开发的整个流程。编程
模型类定义在models.py文件中,继承自models.Model类。bash
说明:不须要定义主键列,在生成时会自动添加,而且值为自动增加。服务器
服务器类:
根据设计,在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自带的迁移的方式,建立数据库表。
上面的一小段用于建立模型的代码给了 Django 不少信息,经过这些信息,Django 能够:
为了在咱们的工程中包含这个应用,咱们须要在配置类 INSTALLED_APPS
中添加设置。由于 AssetinfoConfig
类写在文件 assetinfo/apps.py
中,因此它的点式路径是 'assetinfo.apps.AssetinfoConfig'
。在文件 mysite/settings.py
中 INSTALLED_APPS
子项添加点式路径后,它看起来像这样:
不用死记硬背这个点路径,pycharm会自动提示。
如今你的 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语句来操做它。
从上图能够看到自动建立生成的表以及字段。
细心的读者会发现上面生成的表的名字叫作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
执行以后,能够发现错误以下:
那么怎么解决这个错误呢?
在外键值的后面加上 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
注意上图中assetinfo_middlewareinfo表中有一列server_id,这一列名为何不叫server? server_id是根据MiddlewareInfo类的关系属性server生成的,对应着服务器表中的主键id。
完成数据表的迁移以后,下面就能够经过进入项目的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]:
复制代码