Django 模型(Model)
1. 模型简介
2. 定义模型
3. 模型成员&管理器
4. 模型查询
- 1)查询集方法(select)
- 2)限制查询集(limit)
- 3)查询集缓存
- 4)字段查询&比较运算符(where)
- 5)聚合函数
- 6)F 对象(两字段值比较)
- 7)Q 对象(逻辑运算 and、or、not)
1. 模型简介
ORM 简介
MVC 框架中一个重要的部分就是 ORM,它实现了数据模型与数据库的解耦,即数据模型的设计不需要依赖于特定的数据库,通过简单的配置就可以轻松更换数据库。即直接面向对象操作数据,无需考虑 sql 语句。
ORM 是“对象-关系-映射”的简称,主要任务是:
- 根据对象的类型生成表结构。
- 将对象(或对象列表)的操作,转换为 sql 语句。
- 将 sql 查询到的结果转换为对象(或对象列表)。
这极大的减轻了开发人员的工作量,不需要面对因数据库变更而导致的无效劳动。
Django 中的模型包含了存储数据的字段和约束,对应着数据库中唯一的表。
使用 Mysql 数据库的环境配置
创建数据库
create databases modeldemo charset=utf8
打开应用的 settings.py 文件,修改 DATABASES 项:
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.mysql',
'NAME': 'modeldemo', # 使用的Mysql库名
'USER': '用户名',
'PASSWORD': '密码',
'HOST': '数据库服务器ip,本地可以使用localhost',
'PORT': '端口,默认为3306',
}
}
安装 python mysql API
python3
pip install pymysql
且要在项目的 __init__.py 中添加:
import pymysql
pymysql.install_as_MySQLdb()
否则会出现报错:Error loading MySQLdb module: No module named 'MySQLdb'。
python2
pip install MySQL-python
且不需要在 __init__.py 中添加上述代码。
开发流程
- 在 models.py 中定义模型类,要求继承自 models.Model。
- 把应用加入 settings.py 文件的 installed_app 项。
- 迁移:生成迁移文件;执行迁移并生成表(迁移的目的是映射模型类与表。如果模型类与表的映射关系已存在,则无需迁移)。
- 使用模型类进行 crud(增删改查)操作。
2. 定义模型
在模型中定义属性,会生成表中的字段。
Django 根据属性的类型确定以下信息:
- 当前选择的数据库支持字段的类型(核心)。
- 渲染管理站点表单时使用的默认 html 控件。
- 在管理站点最低限度的验证。
Django 会为表增加自动增长的主键列,每个模型只能有一个主键列,如果使用选项设置某属性为主键列后,则 Django 不会再生成默认的主键列。
属性命名限制:
- 不能是 python 的保留关键字。
- 由于 Django 的查询方式,不允许带有连续的下划线。
1)定义属性
定义属性时,需要明确字段类型。字段类型被定义在 django.db.models.fields 目录下,为了方便使用,被导入到了 django.db.models 中。
使用方式:
from django.db import models
通过 models.Field 创建字段类型的对象,赋值给属性。如:
title = models.CharField(max_length=20)
若想对重要数据都做逻辑删除而不做物理删除,实现方法是定义 isDelete 属性,类型为 BooleanField,默认值为 False。
2)字段类型
- AutoField:一个根据实际 id 自动增长的 IntegerField,通常不指定。
- 如果不指定,一个主键字段将自动添加到模型中。
- BooleanField:true/false 字段,此字段的默认表单控制是 CheckboxInput。
- NullBooleanField:支持 null、true、false 三种值。
- CharField(max_length=最大字符长度):字符串,默认的表单样式是 TextInput。
- TextField:大文本字段,一般超过 4000 字符时使用,默认的表单控件是 Textarea。
- IntegerField:整数。
- DecimalField(max_digits=None, decimal_places=None):使用 python 的 Decimal 实例表示的十进制浮点数。
- DecimalField.max_digits:位数总数。
- DecimalField.decimal_places:小数点后的数字位数。
- FloatField:用 python 的 float 实例来表示的浮点数。
- DateField[auto_now=False, auto_now_add=False]):使用 python 的 datetime.date 实例表示的日期。
- 参数 DateField.auto_now:每次保存对象时,自动设置该字段为当前时间,用于"最后一次修改"的时间戳,它总是使用当前日期,默认为 false。
- 参数 DateField.auto_now_add:当对象第一次被创建时自动设置当前时间,用于创建的时间戳,它总是使用当前日期,默认为 false。
- 该字段默认对应的表单控件是一个 TextInput. 在管理员站点添加了一个 JavaScript 写的日历控件,和一个“Today"的快捷按钮,包含了一个额外的 invalid_date 错误消息键。
- auto_now_add, auto_now, and default 这些设置是相互排斥的,他们之间的任何组合将会发生错误的结果。
- TimeField:使用 python 的 datetime.time 实例表示的时间,参数同 DateField。
- DateTimeField:使用 python 的 datetime.datetime 实例表示的日期和时间,参数同 DateField。
- FileField:一个上传文件的字段。
- ImageField:继承了 FileField 的所有属性和方法,但对上传的对象进行校验,确保它是个有效的 image。
3)字段选项
通过字段选项,可以实现对字段的约束。实现方式是通过字段对象的关键字参数指定。
- null:如果为 True,Django 将空值以 NULL 存储到数据库中,默认值是 False。
- blank:如果为 True,则该字段允许为空白,默认值是 False。
- 对比:null 是数据库范畴的概念,blank 是表单验证证范畴的。
- db_column:字段的名称,如果未指定,则使用属性的名称。
- db_index:若值为 True, 则在表中会为此字段创建索引。
- default:字段的默认值(遗留问题:该选项在数据库中未生效,但在对象操作时有效)。
- primary_key:若为 True, 则该字段会成为模型的主键字段。
- unique:如果为 True, 这个字段在表中必须有唯一值。
4)关系
关系的类型包括:
- ForeignKey:一对多,将字段定义在多的一端中。
- ManyToManyField:多对多,将字段定义在两端中。
- OneToOneField:一对一,将字段定义在任意一端中。
用一访问多:对象.模型类小写_set
bookinfo.heroinfo_set
用一访问一:对象.模型类小写
heroinfo.bookinfo
访问 id:对象.属性_id
heroinfo.book_id
5)元选项
在模型类中定义类 Meta,用于设置元信息。
- 元信息 db_table:定义数据表名称,推荐使用小写字母。
- 数据表的默认名称如下:
<app_name>_<model_name>
- ordering:对象的默认排序字段,获取对象的列表时使用,接收属性构成的列表。
class BookInfo(models.Model):
...
class Meta():
ordering = ['id']
- 字符串前加 - 表示倒序,不加 - 表示正序。
class BookInfo(models.Model):
...
class Meta():
ordering = ['-id']
注意:排序会增加数据库的空间开销。
6)范例
创建 ModelDemo 项目,并创建 book_info 应用,使用 mysql 数据库。
定义图书和英雄模型:
1 from django.db import models
2
3
4 # 定义图书模型
5 class BookInfo(models.Model):
6
7 title = models.CharField(max_length=20)
8 public_date = models.DateField(db_column="pub_date") # 设置在数据库中的实际列名称
9 read_num = models.IntegerField(default=0) # 阅读量
10 comment_num = models.IntegerField(null=False) # 评论数
11 isDelete = models.BooleanField(default=False) # 只做逻辑删除,不做物理删除
12
13 class Meta:
14 db_table = "book_info" # 定义表名
15
16
17 # 定义英雄模型
18 class HeroInfo(models.Model):
19
20 name = models.CharField(max_length=20)
21 gender = models.BooleanField(default=True)
22 content = models.CharField(max_length=1000) # 对英雄的描述
23 isDelete = models.BooleanField(default=False)
24 book = models.ForeignKey(BookInfo)
执行迁移:
python manage.py makemigrations
python manage.py migrate
迁移完成后,在 mysql 查看生成的表信息:
测试数据
模型 BookInfo 的测试数据:
insert into book_info(title,pub_date,read_num,comment_num,isDelete) values
('射雕英雄传','1980-5-1',12,34,0),
('天龙八部','1986-7-24',36,40,0),
('笑傲江湖','1995-12-24',20,80,0),
('雪山飞狐','1987-11-11',58,24,0);
模型 HeroInfo 的测试数据:
insert into book_info_heroinfo(name,gender,book_id,content,isDelete) values
('郭靖',1,1,'降龙十八掌',0),
('黄蓉',0,1,'打狗棍法',0),
('黄药师',1,1,'弹指神通',0),
('欧阳锋',1,1,'蛤蟆功',0),
('梅超风',0,1,'九阴白骨爪',0),
('乔峰',1,2,'降龙十八掌',0),
('段誉',1,2,'六脉神剑',0),
('虚竹',1,2,'天山六阳掌',0),
('王语嫣',0,2,'神仙姐姐',0),
('令狐冲',1,3,'独孤九剑',0),
('任盈盈',0,3,'弹琴',0),
('岳不群',1,3,'华山剑法',0),
('东方不败',0,3,'葵花宝典',0),
('胡斐',1,4,'胡家刀法',0),
('苗若兰',0,4,'黄衣',0),
('程灵素',0,4,'医术',0),
('袁紫衣',0,4,'六合拳',0);
3. 模型成员&管理器
1)类属性
objects(类)属性是 Manager 类型的对象,即管理器对象。
管理器 Manager
- 管理器是模型类的类属性,是 Django 的数据模型与数据库交互的接口,用于将对象与数据表映射。Django 的 ORM 本质上就是通过管理器实现的。
- 当定义模型类时没有指定管理器,则 Django 会为模型类提供一个名为 objects 的管理器。Django 应用的每个模型类都拥有至少一个管理器。
- 如果不想用默认的管理器,可自定义管理器。自定义管理器类主要用于两种情况:
- 情况一:增加模型类的创建方式。
- 情况二:更改管理器返回的查询集:通过重写 get_queryset() 方法。
范例:更改查询结果集
编写自定义管理器类并应用
1 from django.db import models
2
3
4 """自定义管理器"""
5 class BookInfoManager(models.Manager):
6 def get_queryset(self): # 查询操作都会调用此方法
7 # 在父类的默认查询结果上,通过filter()加上自定义的查询逻辑
8 return super(BookInfoManager, self).get_queryset().filter(isDelete=False)
9
10
11 # 定义图书模型
12 class BookInfo(models.Model):
13
14 title = models.CharField(max_length=20)
15 public_date = models.DateField(db_column="pub_date") # 设置在数据库中的实际列名称
16 read_num = models.IntegerField(default=0) # 阅读量
17 comment_num = models.IntegerField(null=False) # 评论数
18 isDelete = models.BooleanField(default=False) # 只做逻辑删除,不做物理删除
19
20 class Meta:
21 db_table = "book_info" # 定义表名
22
23 """应用管理器"""
24 book_raw_manager = models.Manager() # 默认管理器
25 book_my_manager = BookInfoManager() # 自定义管理器
26
27
28 # 定义英雄模型
29 class HeroInfo(models.Model):
30
31 name = models.CharField(max_length=20)
32 gender = models.BooleanField(default=True)
33 content = models.CharField(max_length=1000) # 对英雄的描述
34 isDelete = models.BooleanField(default=False)
35 book = models.ForeignKey(BookInfo)
修改测试数据
使用 python manage.py shell 测试
>>> from book_info.models import BookInfo
>>>
>>> BookInfo.book_raw_manager.all() # 使用默认管理器的查询结果:4条数据
[<BookInfo: BookInfo object>, <BookInfo: BookInfo object>, <BookInfo: BookInfo object>, <BookInfo: BookInfo object>]
>>> BookInfo.book_my_manager.all() # 使用自定义管理器的查询结果:仅返回isDelete为False的两条数据
[<BookInfo: BookInfo object>, <BookInfo: BookInfo object>]
2)实例对象的创建
- 当创建实例对象时,Django 不会对数据库进行读写操作。当调用 save() 方法后才与数据库交互,将对象保存到数据库中。
- 使用关键字参数构造模型对象很麻烦,推荐使用下面的两种方式。
- 说明: _init _ 方法已经在基类 models.Model 中使用,在自定义模型中无法使用。
范例:创建实例对象的两种方式
1 from django.db import models
2
3
4 # 自定义管理器
5 class BookInfoManager(models.Manager):
6
7 def get_queryset(self):
8 # 在父类的默认查询结果上,通过filter()加上自定义的查询逻辑
9 return super(BookInfoManager, self).get_queryset().filter(isDelete=False)
10
11 """创建实例对象的方式一(官方推荐)"""
12 def create(self, title, public_date):
13 book = self.model()
14 book.title = title
15 book.public_date = public_date
16 book.read_num = 0
17 book.comment_num = 0
18 book.isDelete = False
19 return book
20 '''以下方式直接保存了对象,不需要调用save()
21 book = self.create(btitle=title, bpub_date=pub_date, bread=0, bcommet=0, isDelete=False)
22 return book
23 '''
24
25
26 # 定义图书模型
27 class BookInfo(models.Model):
28
29 title = models.CharField(max_length=20)
30 public_date = models.DateField(db_column="pub_date") # 设置在数据库中的实际列名称
31 read_num = models.IntegerField(default=0) # 阅读量
32 comment_num = models.IntegerField(null=False) # 评论数
33 isDelete = models.BooleanField(default=False) # 只做逻辑删除,不做物理删除
34
35 class Meta:
36 db_table = "book_info" # 定义表名
37
38 # 应用管理器
39 book_raw_manager = models.Manager() # 默认管理器
40 book_my_manager = BookInfoManager() # 自定义管理器
41
42 """创建实例对象的方式二"""
43 @classmethod
44 def create(cls, title, public_date):
45 b = cls()
46 b.title = title
47 b.public_date = public_date
48 b.read_num = 0
49 b.comment_num = 0
50 b.isDelete = False
51 return b
52
53
54 # 定义英雄模型
55 class HeroInfo(models.Model):
56
57 name = models.CharField(max_length=20)
58 gender = models.BooleanField(default=True)
59 content = models.CharField(max_length=1000) # 对英雄的描述
60 isDelete = models.BooleanField(default=False)
61 book = models.ForeignKey(BookInfo)
测试
>>> from book_info.models import BookInfo
>>> import datetime
>>>
>>> # 通过类方法创建对象
>>> b1 = BookInfo.create("楚留香1", datetime.date(1988, 3, 1))
>>> b1.save()
>>> # 通过管理器的方法创建对象
>>> b2 = BookInfo.book_my_manager.create("楚留香2", datetime.date(1988, 3, 1))
>>> b2.save()
>>>
3)实例方法
- str(self):重写 object 方法,此方法在将对象转换成字符串时会被调用。
- save():将模型对象保存到数据表中。
- delete():将模型对象从数据表中删除。
4. 模型查询
1)查询集方法(select)
- 查询集表示从数据库中获取的对象集合。
- 过滤器基于所给的参数限制查询的结果。
- 查询集可以含有零个、一个或多个过滤器。
- 从 sql 的角度,查询集和 select 语句等价,过滤器像 where 和 limit 子句。
惰性执行:创建查询集不会带来任何数据库的访问,直到调用数据时,才会访问数据库。实际调用数据的情况如下:
- 迭代
- 序列化
- 与 if 合用
管理器调用查询方法会返回查询集。返回查询集的方法如下:
- all():返回所有数据。
- filter():返回符合条件的数据。
- exclude():返回与条件相反的数据。
- order_by():排序。
- values():一个对象构成一个字典{'属性': '值'},所有对象构成一个列表返回。
过滤器语法:
filter(键1=值1, 键2=值2)
等价于
filter(键1=值1).filter(键2=值2)
查询集经过过滤器筛选后返回新的查询集,因此可以写成链式过滤。
value() 执行结果:
>>> BookInfo.book_my_manager.values() # 等价于 BookInfo.book_my_manager.all().values()
[{'id': 1, 'title': '射雕英雄传', 'public_date': datetime.date(1980, 5, 1), 'read_num': 12, 'comment_num': 34, 'isDelete': False}, {'id': 4, 'title': '雪山飞狐', 'public_date': datetime.date(1987, 11, 11), 'read_num': 58, 'comment_num': 24, 'isDelete': False}, {'id': 7, 'title': '楚留香1', 'public_date': datetime.date(1988, 3, 1), 'read_num': 0, 'comment_num': 0, 'isDelete': False}, {'id': 8, 'title': '楚留香2', 'public_date': datetime.date(1988, 3, 1), 'read_num': 0, 'comment_num': 0, 'isDelete': False}]
返回单个值的方法:
- get():返回单个满足条件的对象。
- 如果未找到,会引发"模型类.DoesNotExist"异常。
- 如果多条被返回,会引发"模型类.MultipleObjectsReturned"异常。
- count():返回当前查询的总条数。
- first():返回第一个对象。
- last():返回最后一个对象。
- exists():判断查询集中是否有数据,如果有则返回 True。
2)限制查询集(limit)
- 返回的查询集列表,可以使用索引或切片的方式进行限制,等同于 sql 中的 limit 和 offset 子句。
- 注意:不支持负数索引。
- 使用下标后返回一个新的查询集,不会立即执行查询(惰性查询)。
- 如果获取一个对象,直接使用[0],等同于[0:1].get()。如果没有数据,[0] 引发 IndexError 异常,[0:1].get() 引发 DoesNotExist 异常。
>>> BookInfo.book_my_manager.all()[0] # 返回对象
<BookInfo: BookInfo object>
>>> BookInfo.book_my_manager.all()[0:1].get() # 返回对象
<BookInfo: BookInfo object>
>>> BookInfo.book_my_manager.all()[0:1] # 返回对象列表
[<BookInfo: BookInfo object>]
3)查询集缓存
每个查询集都包含一个缓存来最小化对数据库的访问。
在新建的查询集中,缓存为空。当首次对查询集求值时,会发生数据库查询,Django 便会将查询的结果存在查询集的缓存中,并返回请求的结果。之后若访问相同的查询集值时将重用缓存的结果。
无法使用缓存的情况:
这构成了两个查询集,无法重用缓存,每次查询都会与数据库进行一次交互,增加了数据库的负载。
print([e.title for e in Entry.objects.all()])
print([e.title for e in Entry.objects.all()])
可以使用缓存的情况:
两次循环使用同一个查询集,第二次使用缓存中的数据。
querylist = Entry.objects.all()
print([e.title for e in querylist])
print([e.title for e in querylist])
何时查询集不会被缓存:
当只对查询集的部分进行求值时会检查缓存,但是如果这部分不在缓存中,那么接下来查询返回的记录将不会被缓存,这意味着使用索引来限制查询集将不会填充缓存。如果这部分数据已经被缓存,则直接使用缓存中的数据。
querylist = Entry.objects.all()
print([e.title for e in querylist[0:10]]) # 使用缓存求子集,但子集的查询结果不会存入缓存
4)字段查询&比较运算符(where)
以下语法作为方法 filter()、exclude()、get() 的参数,从而实现 where 子句。
属性名称__比较运算符=值
- exact:表示判等,大小写敏感;如果没有写“ 比较运算符”,表示判等。
filter(isDelete=False) # 等价于 filter(isDelete__exact=False)
- contains:是否包含,大小写敏感。
filter(btitle__contains='传') # 查找标题包含“传”的数据
- startswith、endswith:匹配开头或结尾,大小写敏感。
filter(btitle__endswith='传')
在前面加个 i 表示不区分大小写,如 iexact、icontains、istarswith、iendswith。
- isnull、isnotnull:是否为 null。
filter(btitle__isnull=False)
- in:是否包含在范围内。
filter(pk__in=[1, 2, 3, 4, 5])
- gt、gte、lt、lte:大于、大于等于、小于、小于等于。
filter(id__gt=3)
- year、month、day、week_day、hour、minute、second:对日期间类型的属性进行运算。
filter(public_date__year=1980)
filter(public_date__gt=date(1980, 12, 31))
- 关联关系的查询:处理 join 查询。
- 语法:模型类名__属性名__比较运算符
- 可反向使用,即在关联的两个模型中都可以使用。
>>> BookInfo.book_my_manager.filter(heroinfo__content__contains="八").values() # 查询英雄对象的描述字段中含有“八”的图书数据
[{'id': 1, 'title': '射雕英雄传', 'public_date': datetime.date(1980, 5, 1), 'read_num': 12, 'comment_num': 34, 'isDelete': False}]
- 快捷查询的属性 pk:pk 表示 primary key,默认的主键是 id。
filter(pk__lt=6) # 查询主键为6的数据
- 对于 like 语句中使用的 %,在过滤器中无需转义。
filter(title__contains="%") # 等价于 where title like '%\%%',表示查找标题中包含 % 的数据。
5)聚合函数
使用 aggregate() 函数返回聚合函数的值。
- Count、Avg、Max、Min、Sum 的用法:
from django.db.models import Max >>> BookInfo.book_my_manager.aggregate(Max('public_date')) # 查找出版日期最晚的书
{'public_date__max': datetime.date(1988, 3, 1)}
- count 的一般用法:
>>> BookInfo.book_my_manager.aggregate(Count('public_date'))
{'public_date__count': 4}
>>> BookInfo.book_my_manager.count() # 直接得到数值
4
6)F 对象(两字段值比较)
- 可以使用模型的字段 A 与字段 B 进行比较,如果 A 写在了等号的左边,则 B 出现在等号的右边,需要通过 F 对象构造。
>>> from django.db.models import F
>>>
BookInfo.book_my_manager.filter(read_num__gt=F('comment_num')).values() # 查找阅读量 > 评论量的数据
[{'id': 4, 'title': '雪山飞狐', 'public_date': datetime.date(1987, 11, 11), 'read_num': 58, 'comment_num': 24, 'isDelete': False}]
>>>
- django 支持对 F() 对象使用算数运算。
BookInfo.book_my_manager.filter(read_num__gt=F('comment_num')*2)
- F() 对象中还可以写作“模型类__列名”进行关联查询。
>>> BookInfo.book_my_manager.filter(isDelete=F('heroinfo__isDelete')).values()
[{'id': 1, 'title': '射雕英雄传', 'public_date': datetime.date(1980, 5, 1), 'read_num': 12, 'comment_num': 34, 'isDelete': False}, {'id': 1, 'title': '射雕英雄传', 'public_date': datetime.date(1980, 5, 1), 'read_num': 12, 'comment_num': 34, 'isDelete': False}, {'id': 1, 'title': '射雕英雄传', 'public_date': datetime.date(1980, 5, 1), 'read_num': 12, 'comment_num': 34, 'isDelete': False}, {'id': 1, 'title': '射雕英雄传', 'public_date': datetime.date(1980, 5, 1), 'read_num': 12, 'comment_num': 34, 'isDelete': False}, {'id': 1, 'title': '射雕英雄传', 'public_date': datetime.date(1980, 5, 1), 'read_num': 12, 'comment_num': 34, 'isDelete': False}, {'id': 4, 'title': ' 雪山飞狐', 'public_date': datetime.date(1987, 11, 11), 'read_num': 58, 'comment_num': 24, 'isDelete': False}, {'id': 4, 'title': '雪山飞狐', 'public_date': datetime.date(1987, 11, 11), 'read_num': 58, 'comment_num': 24, 'isDelete': False}, {'id': 4, 'title': '雪山飞狐', 'public_date': datetime.date(1987, 11, 11), 'read_num': 58, 'comment_num': 24, 'isDelete': False}, {'id': 4, 'title': '雪山飞狐', 'public_date': datetime.date(1987, 11, 11), 'read_num': 58, 'comment_num': 24, 'isDelete': False}]
- 对于 date/time 字段,可与 timedelta() 进行运算。
>>> from datetime.datetime import timedelta
>>>
>>> BookInfo.book_my_manager.filter(public_date__lt=F('public_date')+timedelta(days=1))
[<BookInfo: BookInfo object>, <BookInfo: BookInfo object>, <BookInfo: BookInfo object>, <BookInfo: BookInfo object>]
7)Q 对象(逻辑运算 and、or、not)
需要进行 and、or、not 查询时,可以使用 Q() 对象。
- Q 对象(django.db.models.Q)用于封装一组关键字参数,这些关键字参数与“比较运算符”中的相同:
>>> from django.db.models import Q
>>>
>>> BookInfo.book_my_manager.filter(Q(pk__lt=2)).values()
[{'id': 1, 'title': '射雕英雄传', 'public_date': datetime.date(1980, 5, 1), 'read_num': 12, 'comment_num': 34, 'isDelete': False}]
- Q 对象可以使用 &(and)、|(or)操作符组合起来。当操作符应用在两个 Q 对象时,会产生一个新的 Q 对象。
>>> # 实现逻辑与,三者等价
>>> BookInfo.book_my_manager.filter(pk__lt=10).filter(pk__gt=2)
[<BookInfo: BookInfo object>, <BookInfo: BookInfo object>, <BookInfo: BookInfo object>]
>>> BookInfo.book_my_manager.filter(pk__lt=10, pk__gt=2)
[<BookInfo: BookInfo object>, <BookInfo: BookInfo object>, <BookInfo: BookInfo object>]
>>> BookInfo.book_my_manager.filter(Q(pk__lt=10) & Q(pk__gt=2))
[<BookInfo: BookInfo object>, <BookInfo: BookInfo object>, <BookInfo: BookInfo object>]
>>>
>>> # 实现逻辑或
>>> BookInfo.book_my_manager.filter(Q(pk__lt=3) | Q(pk__gt=10))
[<BookInfo: BookInfo object>]
- 使用 ~ 操作符在 Q 对象前表示取反(not)。
>>> BookInfo.book_my_manager.filter(~Q(pk__lt=3)) # 表示主键不小于3
Django 模型(Model)的更多相关文章
- Django模型Model的定义
概述 Django对各种数据库提供了很好的支持,Django为这些数据库提供了统一的调用API,可以根据不同的业务需求选择不同的数据库. 模型.属性.表.字段间的关系 一个模型类在数据库中对应一张表, ...
- Django模型model Field详解:
类型说明 AutoField一个自动增加的整数类型字段.通常你不需要自己编写它,Django会自动帮你添加字段:id = models.AutoField(primary_key=True),这是一个 ...
- Django:模型model和数据库mysql(一)
以一个栗子尝试来记录: 两个表存储在数据库中,BookInfo表示书,HeroInfo表示人物.一本书中有多个人物 在MySQL中新建一个数据库Django1,不用创建表,用Django模型来配置数据 ...
- Django之模型(model)中的choices字段的使用
转载自:http://quke.org/post/django-model-choices.html Django模型中的字段有个choices属性,这个属性可以提供被选数据,choices的参数是一 ...
- Django 模型系统(model)&ORM--基础
ORM 映射关系: 类 ---> 表 属性 ---> 字段 对象 --->一条数据 创建表(建立模型) 实例:我们来假定下面这些概念,字段和关系 作者模型:一个作者有姓名和年龄. 作 ...
- django (四) model模型
models模型 1. models 定义属性 概述 django根据属性的类型确定以下信息 ·当前选择的数据库支持字段的类型 ·渲染管理表单时使用的默认html控件 ·在管理站点最低限度的验证 dj ...
- 如何让django模型中的字段和model名显示为中文
如何让django模型中的字段和model名显示为中文:在模型中加入class Meta即可 class People(models.Model): name = models.CharField(n ...
- Django模型(model)系统
Object Relational Mapping(ORM) ORM介绍 ORM概念 对象关系映射(Object Relational Mapping,简称ORM)模式是一种为了解决面向对象与关系数据 ...
- Django 小实例S1 简易学生选课管理系统 9 创建课程模型(model)
Django 小实例S1 简易学生选课管理系统 第9节--创建课程模型(model) 点击查看教程总目录 作者自我介绍:b站小UP主,时常直播编程+红警三,python1对1辅导老师. 对于课程模块, ...
- Django 小实例S1 简易学生选课管理系统 3 创建用户模型(model)
Django 小实例S1 简易学生选课管理系统 第3节--创建用户模型(model) 点击查看教程总目录 作者自我介绍:b站小UP主,时常直播编程+红警三,python1对1辅导老师. 本文涉及到的新 ...
随机推荐
- VUE实现富文本编辑以及组件传值的使用总结
VUE实现使用富文本编辑,如下图: 实现这个富文本编辑需要以下步骤: 第一步:安装编辑器组件 npm install vue-quill-editor –-save第二步:创建一个Ue.vue的文件, ...
- Vue前端项目的搭建流程
1. 安装Vue和Nodejs 2. 创建项目 vue create eduonline-web
- css 超过一行省略号
//超过一行省略号 overflow: hidden; white-space: nowrap; text-overflow: ellipsis; //超过两行省略号 overflow: hidden ...
- 苹果M1处理器Mac“翻车”:用户吐槽SSD
SSD如今被不少PC用户所推崇,其优势在于读写速度快.工作无噪音,不过,缺点是寿命较机械硬盘差点.厂商对SSD通常都会标注一个最大可写入量(TBW),提醒用户关注健康数据,以免掉盘等严重问题. 越来越 ...
- 16. 使用vue3结构及配置管理
主要内容: vue-cli2和3的区别 创建vue-cli3脚手架 vue-cli3项目的目录结构 vue-cli2和vue-cli3中 main.js文件的区别 vue-cli3的配置文件管理 一. ...
- FreeBSD 日常应用
freebsd日常应用 办公libreoffice或者apache openoffice 设计 图像编辑:gimp 矢量图设计:lnkscape 视频剪辑:openshot 视频特效:natron 编 ...
- python面试题,print写在for循环内和外的区别
1.统计列表中正数和负数的数量a = [1,3,5,7,0,-1,-9,-4,-5,8]b = []c = []for i in a : if i>0: b.append(i) elif i&l ...
- Go Module实战:基于私有化仓库的GO模块使用实践
新年开工近一月,2021 年第一期 Open Talk 定档 3 月 18 日晚 8 点,本期我们邀请到了又拍云资深后端开发工程师刘云鹏和我们一起聊聊 Go 最新特性 Go Module 实战. 刘云 ...
- 【Git】敏感信息保护
保护Git仓库敏感信息 代码中无可避免有一些敏感信息,包含但不限于,数据库信息,密钥,账号信息等等.通常我们会把这些信息放在配置文件,这些信息若泄露会造成安全问题. 以前我们做法,是把配置文件通过.g ...
- 第一个win32程序
vs2017下自动创建的窗口程序 // win_test.cpp : 定义应用程序的入口点. // #include "framework.h" #include "wi ...