数据模型(models)

自学python如何成为大佬(目录):https://blog.csdn.net/weixin_67859959/article/details/139049996?spm=1001.2014.3001.5501

(1)在App中添加数据模型

在app1的models.py中添加如下代码:

from django.db import models # 引入django.db.models模块

class Person(models.Model):

"""

编写Person模型类,数据模型应该继承于models.Model或其子类

"""

第一个字段使用models.CharField类型

first_name = models.CharField(max_length=30)

第二个字段使用models.CharField类型

last_name = models.CharField(max_length=30)

Person模型中的每一个属性都指明了models下面的一个数据类型,代表了数据库中的一个字段。上面的类在数据库中会创建如下的表:

CREATE TABLE myapp_person (

"id" serial NOT NULL PRIMARY KEY,

"first_name" varchar(30) NOT NULL,

"last_name" varchar(30) NOT NULL

);

对于一些公有的字段,为了简化代码,可以使用如下的实现方式:

from django.db import models # 引入django.db.models模块

class CreateUpdate(models.Model): # 创建抽象数据模型,同样要继承于models.Model

创建时间,使用models.DateTimeField

created_at = models.DateTimeField(auto_now_add=True)

修改时间,使用models.DateTimeField

updated_at = models.DateTimeField(auto_now=True)

class Meta: # 元数据,除了字段以外的所有属性

设置model为抽象类。指定该表不应该在数据库中创建

abstract = True

class Person(CreateUpdate): # 继承CreateUpdate基类

first_name = models.CharField(max_length=30)

last_name = models.CharField(max_length=30)

class Order(CreateUpdate): # 继承CreateUpdate基类

order_id = models.CharField(max_length=30, db_index=True)

order_desc = models.CharField(max_length=120)

这时,我们用于创建日期和修改日期的数据模型就可以继承于CreateUpdate类了。

上面讲解了数据模型的创建方式,下面介绍django.db.models提供的常见的字段类型,如表5所示。

表5 Django数据模型中常见字段类型及说明

|------------------|------------------------------------------------------------------------------------------|
| 字 段 类 型 | 说 明 |
| AutoField | 一个id自增的字段,但创建表过程Django会自动添加一个自增的主键字段 |
| BinaryField | 一个保存二进制源数据的字段 |
| BooleanField | 一个布尔值的字段,应该指明默认值,管理后台中默认呈现为CheckBox形式 |
| NullBooleanField | 可以为None值的布尔值字段 |
| CharField | 字符串值字段,必须指明参数max_length值,管理后台中默认呈现为TextInput形式 |
| TextField | 文本域字段,对于大量文本应该使用TextField。管理后台中默认呈现为Textarea形式 |
| DateField | 日期字段,代表Python中datetime.date的实例。管理后台默认呈现TextInput形式 |
| DateTimeField | 时间字段,代表Python中datetime.datetime实例。管理后台默认呈现TextInput |
| EmailField | 邮件字段,是CharField的实现,用于检查该字段值是否符合邮件地址格式 |
| FileField | 上传文件字段,管理后台默认呈现ClearableFileInput形式 |
| ImageField | 图片上传字段,是FileField的实现。管理后台默认呈现ClearableFileInput形式 |
| IntegerField | 整数值字段,在管理后台默认呈现NumberInput或者TextInput形式 |
| FloatField | 浮点数值字段,在管理后台默认呈现NumberInput或者TextInput形式 |
| SlugField | 只保存字母数字和下划线和连接符,用于生成url的短标签 |
| UUIDField | 保存一般统一标识符的字段,代表Python中UUID的实例,建议提供默认值default |
| ForeignKey | 外键关系字段,需提供外检的模型参数,和on_delete参数(指定当该模型实例删除的时候,是否删除关联模型),如果要外键的模型出现在当前模型的后面,需要在第一个参数中使用单引号 |
| ManyToManyField | 多对多关系字段,与ForeignKey类似 |
| OneToOneField | 一对一关系字段,常用于扩展其他模型 |

(2)执行数据库迁移

1)创建完数据模型后,开始做数据库迁移,首先我们不希望用Django默认自带的SQLite数据库,我们想使用MySQL数据库,在项目的settings.py配置文件中找到如下的配置:

DATABASES = {

'default': {

'ENGINE': 'django.db.backends.sqlite3',

'NAME': os.path.join(BASE_DIR, 'db.sqlite3'),

}

}

替换为:

DATABASES = {

'default': {

'ENGINE': 'django.db.backends.mysql',

'NAME': 'demo',

'USER': 'root',

'PASSWORD': '您的数据库密码'

}

}

2)创建数据库,在终端连接数据库,执行以下命令:

mysql -u root -p

3)按照提示输入您的数据库密码,连接成功后执行如下语句创建数据库。

create database demo default character set utf8;

创建成功后,即可在Django中使用数据库迁移,并在MySQL中创建数据表了。创建数据库命令执行效果如图21所示。

图21 创建数据库命令执行效果

4)安装数据库的驱动,Python 3.x使用pymysql作为MySQL的驱动,命令如下:

pip install pymysql

5)然后找到"D:\Webprojcets\demo\demo\init.py"文件,在行首添加如下代码:

import pymysql

pymysql.install_as_MySQLdb() # 为了使pymysql发挥最大数据库操作性能

6)执行以下命令,用来创建数据表。

python manage.py makemigrations # 生成迁移文件

python manage.py migrate # 迁移数据库,创建新表

7)创建数据表的效果如图22所示。

图22 创建数据表效果图

创建完成后,即可在数据库中查看这两张数据表了,Django会默认按照"app名称+下划线+模型类名称"的形式创建数据表,对于上面这两个模型,Django创建了如下表:

l Person类对应app1_person表

l Order类对应app1_order表

CreateUpdate是个抽象类,不会创建表结构,在数据库管理软件中查看创建的数据表,效果如图23所示。

图23 在数据库管理软件中查看创建的数据表

(3)了解Django数据API

这里所有的命令将在Django的交互命令行中执行,在项目根目录下启用交互命令行,执行以下命令:

python manage.py shell # 启用交互命令行

导入数据模型命令:

from app1.models import Person, Order # 导入Person和Order两个类

1)创建数据有如下两种方法:

l 方法1

p = Person.objects.create(first_name="hugo", last_name="zhang")

l 方法2

p=Person(first_name="hugo", last_name="张")

p.save() # 必须调用save()才能写入数据库

2)查询数据

l 查询所有数据

Person.objects.all()

l 查询单个数据

Person.objects.get(first_name="hugo") # 括号内需要加入确定的条件,因为get方法只返回一个确定值

l 查询指定条件的数据

Person.objects.filter(first_name__exact="hugo") # 指定first_name字段值必须为hugo

Person.objects.filter(last_name__iexact="zhang") # 指定last_name字段值必须为zhang,且忽略大小写

Person.objects.filter(id__gt=1) # 查找所有id值大于1的

Person.objects.filter(id__lt=100) # 查找所有id值小于100的

排除所有创建时间大于现在时间的,exclude的用法是排除,和filter正好相反

Person.objects.exclude(created_at__gt=datetime.datetime.now(tz=datetime.timezone.utc))

过滤出所有first_name字段值包含h的然后将之前的查询结果按照id进行排序

Person.objects.filter(first_name__contains="h").order_by('id')

Person.objects.filter(first_name__icontains="h") # 查询所有first_name值不包含h的

3)修改查询到的数据

修改之前需要查询到对应的数据或者数据集,代码如下:

p = Person.objects.get(first_name="hugo")

然后按照需求进行修改,例如:

p.first_name = "john"

p.last_name = "wang"

p.save()

注意:必须调用save()方法才能保存到数据库。

当然也可以使用get_or_create,如果数据存在就修改,不存在就创建,代码如下:

p, is_created = Person.objects.get_or_create(

first_name="hugo",

defaults={"last_name": "wang"}

)

get_or_create返回一个元组,一个数据对象和一个布尔值,defaults参数是一个字典。当获取数据的时候defaults参数里面的值不会被传入,也就是获取的对象只存在defaults之外的关键字参数的值。

4)删除数据

删除数据同样需要你先查找到对应的数据,然后进行删除,代码如下:

Person.objects.get(id=1).delete()

(1,({'app1.Person':1}))

技巧:大多数情况下我们不会直接删除数据库中的数据,我们希望在数据模型定义的时候,添加一个status字段,值为True和False,用来标记该数据是否是可用状态。在想要删除该数据的时候,将其值置为False即可。

相关推荐
JH30735 分钟前
Oracle与MySQL中CONCAT()函数的使用差异
数据库·mysql·oracle
蓝染-惣右介7 分钟前
【MyBatisPlus·最新教程】包含多个改造案例,常用注解、条件构造器、代码生成、静态工具、类型处理器、分页插件、自动填充字段
java·数据库·tomcat·mybatis
冷心笑看丽美人8 分钟前
Spring框架特性及包下载(Java EE 学习笔记04)
数据库
LZXCyrus13 分钟前
【杂记】vLLM如何指定GPU单卡/多卡离线推理
人工智能·经验分享·python·深度学习·语言模型·llm·vllm
Enougme16 分钟前
Appium常用的使用方法(一)
python·appium
懷淰メ21 分钟前
PyQt飞机大战游戏(附下载地址)
开发语言·python·qt·游戏·pyqt·游戏开发·pyqt5
hummhumm35 分钟前
第 22 章 - Go语言 测试与基准测试
java·大数据·开发语言·前端·python·golang·log4j
hummhumm1 小时前
第 28 章 - Go语言 Web 开发入门
java·开发语言·前端·python·sql·golang·前端框架
hgdlip1 小时前
主IP地址与从IP地址:深入解析与应用探讨
网络·网络协议·tcp/ip
武子康1 小时前
Java-07 深入浅出 MyBatis - 一对多模型 SqlMapConfig 与 Mapper 详细讲解测试
java·开发语言·数据库·sql·mybatis·springboot