模型
ORM
介绍
O(objects):类和对象。
R(Relation):关系,关系数据库中的表格。
M(Mapping):映射。
功能
- 建立模型类和表之间的对应关系,允许我们通过面向对象的方式来操作数据库。
- 根据设计的模型类生成数据库中的表格。
- 通过方便的配置就可以进行数据库的切换。
数据库配置
Django默认的数据库为sqlite,虽然方便但是性能不好。
注:并且Django只会生成数据表不会生成数据库,数据库需自己创建。
# settings.py
DATABASES = {
"default": {
"ENGINE": "django.db.backends.mysql",
# 数据库名字
"NAME": "test",
# 数据库用户名
"USER": "root",
# 数据库密码
"PASSWORD": "123456",
# 数据库IP
"HOST": "127.0.0.1",
# 数据库端口
"PORT": "3306",
}
}
安装依赖
Django使用mysql需要安装依赖
pip install mysqlclient
模型类字段
Django会为表创建一个自动增长的主键列,每个模型只能有一个主键列,如果使用属性选项设置某属性为主键列后Django不会再创建自动增长的主键列。默认创建的主键列属性为id,可以使用pk(primary key)代替。
1.字段命名限制
1)不能是python的关键字
2)不允许使用连续的下划线,django的查询方式有连续的下划线的语法。
3)定义字段是需要指定字段类型,通过字段类型的参数指定选项,语法如下:
# 需要导入django.db.models的包
属性名=models.字段类型(选项)
- 常用的字段类型
类型 | 描述 |
---|---|
AutoField | 自动增长的IntegerField,通常不用指定,不指定时Django会自动创建 |
属性名为id的自动增长属性。 | |
BooleanField | 布尔字段,值为True或False |
charField(max_length=最大长) | 字符串。参数max_length表示最大字符个数 |
IntegerField | 整数 |
DecimalField(max digits=None | |
decimal_places=None) | 十进制浮点数。参数max digits表示总位。参数decimal_places表示小 |
数位数。 |
- 字段选项
选项名字 | 描述 |
---|---|
default | 默认值。设置默认值. |
primary_key | 若为True,则该字段会成为模型的主键字段,默认值是False,一般作为AutoField的选项使用。 |
unique | 如果为True,这个字段在表中必须有唯一值,默认值是False。 |
db index | 若值为True,则在表中会为此字段创建索引,默认值是False。 |
db column | 字段的名称,如果未指定则使用属性的名称 |
null | 如果为True,表示允许为空,默认值是False。 |
blank | 如果为True,则该字段允许为空,默认值是False。 |
verbose name | 字段的一个人类可读名称 (admin字段显示的名称) |
help text | 额外的“帮助”文本 |
对比: null是数据库范畴的概念,blank是后台管理页面表单验证范畴的。 | |
经验:当修改模型类之后,如果添加的选项不影响表的结构,则不需要重新做迁移,商品的选项中default和blank不影响表结构。 |
-
关系字段类型
Django 中常用的关系字段类型有: -
ForeignKey:一对多关系(一个模型实例关联多个其他模型实例)
-
OneToOneField:一对一关系(一个模型实例关联一个其他模型实例)
-
ManyToManyField:多对多关系(多个模型实例互相关联)
-
ParentalKey:父子关系(使用于继承模型)
-
GenericForeignKey:通用关系(允许任意模型实例之间建立关系)
其中,ForeignKey 和 OneToOneField 都是基于外键实现的关系字段类型,而 ManyToManyField 是通过中间关系表实现的关系,ParentalKey 是通过继承实现的关系,GenericForeignKey 则是比较灵活的一种关系类型,可以与任意模型实例建立关系。
*注:on_delete参数是在Django中定义模型时ForeignKey字段的一个可选参数,它指定了当关联的外键对象被删除时,相关对象的行为。有以下几种选项:
- CASCADE:级联删除。当关联的外键对象被删除时,所有相关对象都将被删除。
- PROTECT:保护。当尝试删除关联的外键对象时,会引发ProtectedError异常,从而防止删除操作。
- SET_NULL:设置为NULL。当关联的外键对象被删除时,将把该字段设置为NULL。要使用此选项,必须将外键字段设置为nullable=True。
- SET_DEFAULT:设置为默认值。当关联的外键对象被删除时,将使用默认值来替换它。要使用此选项,必须将外键字段设置为default。
- SET():设置指定值。当关联的外键对象被删除时,将把该字段设置为指定的值。例如,on_delete=models.SET(‘foo’)将把该字段设置为’foo’。
默认选项是CASCADE,如果不指定on_delete参数,将会使用默认选项。on_delete参数是在Django中定义模型时ForeignKey字段的一个可选参数,它指定了当关联的外键对象被删除时,相关对象的行为。有以下几种选项: - CASCADE:级联删除。当关联的外键对象被删除时,所有相关对象都将被删除。
- PROTECT:保护。当尝试删除关联的外键对象时,会引发ProtectedError异常,从而防止删除操作。
- SET_NULL:设置为NULL。当关联的外键对象被删除时,将把该字段设置为NULL。要使用此选项,必须将外键字段设置为nullable=True。
- SET_DEFAULT:设置为默认值。当关联的外键对象被删除时,将使用默认值来替换它。要使用此选项,必须将外键字段设置为default。
- SET():设置指定值。当关联的外键对象被删除时,将把该字段设置为指定的值。例如,on_delete=models.SET(‘foo’)将把该字段设置为’foo’。
默认选项是CASCADE,如果不指定on_delete参数,将会使用默认选项。*
下面是一个简单的Django模型示例:
from django.db import models
class Book(models.Model):
title = models.CharField(max_length=200)
author = models.CharField(max_length=100)
publisher = models.CharField(max_length=100)
publish_date = models.DateField()
class Meta:
# 自定义表名,默认为应用名_模型类名小写
db_table='Book'
# 表的说明信息,在Django后天可以看到
verbose_name = '购物车表'
verbose_name_plural = verbose_name
def __str__(self):
return self.title
"""
这个模型定义了一个Book类,它继承自models.Model,表明它是一个Django模型。Book类有四个字段:title(标题)、author(作者)、publisher(出版社)和publish_date(出版日期)。每个字段都是一个models.CharField对象,定义了它们的类型和最大长度。 __str__ 方法指定了对象以字符串的形式表示自己时所返回的内容(如此例中将会返回Book对象的title属性值)。
"""
- 模型迁移命令
Django模型迁移命令可以使用以下两个命令:
-
python manage.py makemigrations
:此命令会检测您的应用程序中的模型更改,并生成迁移文件。 -
python manage.py migrate
:此命令会应用最新的迁移文件,将更改应用于数据库。
其他一些有用的模型迁移命令:
-
python manage.py showmigrations
:此命令将显示所有模型的可用迁移文件。 -
python manage.py migrate <app_name>
:此命令将应用某个应用程序的所有迁移文件。 -
python manage.py migrate <app_name> <migration_name>
:此命令将应用某个应用程序的指定迁移文件。 -
python manage.py migrate --fake <migration_name>
:此命令将标记某个迁移文件为已应用,但不会将更改应用到数据库。Django模型迁移命令可以使用以下两个命令:
-
python manage.py makemigrations
:此命令会检测您的应用程序中的模型更改,并生成迁移文件。 -
python manage.py migrate
:此命令会应用最新的迁移文件,将更改应用于数据库。
其他一些有用的模型迁移命令:
-
python manage.py showmigrations
:此命令将显示所有模型的可用迁移文件。 -
python manage.py migrate <app_name>
:此命令将应用某个应用程序的所有迁移文件。 -
python manage.py migrate <app_name> <migration_name>
:此命令将应用某个应用程序的指定迁移文件。 -
python manage.py migrate --fake <migration_name>
:此命令将标记某个迁移文件为已应用,但不会将更改应用到数据库。
- 模型的查询
# 示例
from news.models import NewsType,NewsInfo
NewsType.objects.get(id=1)
"""
get方法查询一条数据
Demo查询id为1的数据
只能查询到唯一符合的数据
查询数据不存在直接报错
查询到多条符合条件的也会报错
"""
Django模型查询方法指的是使用Django提供的ORM(对象关系映射)工具,在应用程序中查询数据库中的数据的方法。以下是常用的Django模型查询方法:
查询集
-
all()方法:查询模型中的所有记录。
-
filter()方法:根据特定条件筛选记录。
-
exclude()方法:排除符合特定条件的记录。
-
get()方法:根据特定条件获取单个对象。
-
order_by()方法:按照指定的字段排序。(降序排序在属性前加-)
条件查询
6. values()方法:返回指定字段的值。
-
count()方法:统计查询结果的数量。
-
distinct()方法:去除重复的查询结果。
-
annotate()方法:对查询结果进行聚合计算,例如求和、平均值等。
-
prefetch_related()方法:使用前向关联查询关联对象。
-
select_related()方法:使用后向关联查询关联对象。
-
Q对象:用于构造高级查询条件,例如可以使用Q对象实现and和or查询。
使用这些Django模型查询方法,可以在应用程序中轻松地查询数据库中的数据。
查询集
all,filter,exclude,order_by 调用这这些函数会产生一个查询集 (QuerySet)查询集可以继续调用上面的
所有函数。可以通过exists判断一个查询集中是否有数据。
查询集特性
- 惰性查询: 只有在实际使用查询集中的数据的时候才会发生对数据库的真正查询
- 缓存:当使用的是同一个查询集时]第一次使用的时候会发生实际数据库的查询,然后把结果缓存起来 之后再使用这个查询集时,使用的是缓存中的结果。
模糊条件查询
#条件语法格式
模型类.objects.filter(模型类属性名__条件名=值)
"""
1. contains:包含查询:
Demo:查询新闻类型名称中包含 “新闻"这两个字的数据
NewsType.objects.fiter(name__contains='新闻)
2. startswith:查询以xxx开头:
Demo:查询以科技开头的新闻类别
NewsType.objects.filter(name__startswith='新闻')
3. endswith:查询以XXX结尾:
NewsType.objects.filter(name__endswith='新闻')
4. in:查询某个范围类的数据
Demo:查询id为1.3.5的数据
NewsType.objects.filter(id__in=[1,3,5])
查询的比较运算符
1、gt: 大于
Demo: 查询id大于3的数据
NewsType.objects.filter(id__gt=3)
2、lt: 小于
Demo:查询id小于5的数据
NewsType.objects.filter(id__Tt=5)
3、 gte:大于等于
4、 lte: 小于等于
"""
Q和F对象
Q对象: 用来比较查询数据两个属性
"""
导入:
from django .db .modes import F
Demo: 查询阅读量等于评论数量的新闻
NewsInfo.objects.filter(read=F('comment'))
Demo2: 查询阅读量 大于评论数量~2倍 的新闻
NewsInfo.objects.filter(read__gt=F('commen')*2 )
备注: F对象查询的结果可以直接进行算数运算
"""
F对象逻辑查询(与或非)
"""
from django .db .modes import Q
1、逻辑与: 多个条件同时成立
不使用Q对象:
Demo:查询阅读数量大于40,评论数量大于35的数据
NewSInfo.objects.filter(read__gt=40,comment__gt=35)
使用Q对象
NewsInfo.objects.fiter(q(read__gt=40) & Q(comment__gt=35))
2、逻辑或:多个条件符合一个即可
Demo: 查询阅读数量大于30,或者评论数量大于3@的数据
NewsInfo.objects.filter(Q(read__get=30)|(comment__gt=30))
3、逻辑非:查询不符合条件的
通过 exclude方法查询:
Demo:查询id不为1的数据
NewsInfo.objects.exclude(id=1)
通过Q对象查询:
NewsInfo.objects.exclude(~Q(id=1))
"""
聚合函数
"""
聚合函数: sum、avg、max、min、count:
导入:
from django.db.models import Sum,Avg,Max,Min, Count
结合aggregate方法使用:
NewsInfo.objects.all () .aggregate(Max('read'))
"""
模型关联查询
"""
模型类关联查询:
1、通过对象进行关联查询:
由一到多的查询:
Demo:查询id为1的书籍中所有的人物:
book1 = Book.objects.get(id=1)
# 对象.模型名_set.all()
book1.her_set.all()
由多到一的查询:
Demo:查询id为1这个人物所属书籍
p1 = Hero.objects.get(id=1)
通过关联字段就可以直接获取到关联的数据对象
b1 = p1.book
2、通过模型类进行关联查询:
由一到多的条件查询:
语法:
关联模型类名小写__属性__比较方法 = 值
Demo:查找书籍中人物名字带峰的书籍
Book.objects.filter(hero__name__contains='峰')
由多到一的条件查询:
语法:
关联字段__届性__条件 = 值
Demo:查询天龙八部中的所有人物:
Hero.objects.filter(book__name='天龙八部
"""