表内查询
以下方法都是跟随在objects后面:
all()
方法 all() 返回了一个包含数据库中所有对象的 QuerySet 对象,一般不直接使用,可跟着字段使用.
all_entries = Entry.objects.all()
values()
Entry.objects.values('id')
返回一个列表,每条数据是字典的形式
values_list()
Entry.objects.values_list('id')
返回一个元组,元组不允许修改.
get()
输出一条记录,注意当没有数据或有多条数据时会报错;get输出的不是queryset!
all_entries = Entry.objects.get(number=2)
namber是表的字段名,2是字段值.
filter()
和get()对比,可以输出一条或多条数据queryset,当数据不存在时会返回空值[],不会报错.
all_entries = Entry.objects.filter(number=2)
count()
返回一个整数,表示数据库中与 QuerySet
匹配的对象数量。
Entry.objects.count()
len()
这将返回结果列表的长度。一般用于字符串
order_by()
按照字段排序,如日期,字母,数字,当使用'-'时,倒序.
Entry.objects.filter(pub_date__year=2005).order_by('-pub_date', 'headline')
当参数为空时,按主键排列.
reverse()
倒序输出,可切片, 一般只应在有定义顺序的QuerySet()中使用.
my_queryset.reverse()[:5]
get()和filter()的条件匹配符号,字段名后缀.
- 可以在调用 values() 之后调用 filter()、order_by() 等,也就是说这两个调用是相同的:
- 基本上都可以组合排列使用.
- 一对一关系 OneToOneField()
- 一对多关系ForeignKey()
- 多对多关系ManyToManyField()
表间的查询
主表和从表;正向查询和反向查询;
一对一查询:
创建model:
class A(models.Model):
A_name = models.OneToOneField(
to_field='id',#关联字段
to='B',#关联表名
on_delete=models.CASCADE,#关系
null=True,
verbose_name='主题',
blank=True
)
class B(models.Model):
B_name = models.TextField(
max_length=20,
verbose_name='问题',
null=True,
default="问题限制40个字节"
)
OneToOneField()可以放在所在的表为主表A,关联的表B为从表,主要用于关联操作,删除或添加,主表删除
正向查询
#获取A表值,查询B表关联字段
B_n = B.objects.get(id=2)#获取从表B的字段值
A_n = B_name.A.A_name#根据关联字段查询主表的关联字段值
反向查询
A_n = A.objects.get(id=2)#获取主表A的字段值
B_n = A_n.b.B_name#根据关联字段查询从表的对应字段值;表名要小写.
- 这里一般使用get()保证记录的唯一性.
- 正向和反向的查询获取的值是一条记录,使用属性,
- 表名小写
一对多查询
创建model:
class A(models.Model):
A_name = models.ForeignKey()(
'B',#关联表名
on_delete=models.CASCADE,#关系
null=True,
verbose_name='主题',
)
class B(models.Model):
B_name = models.TextField(
max_length=20,
verbose_name='问题',
null=True,
default="问题限制40个字节"
)
正向查询
#获取B表值,查询A表关联字段
B_n = B.objects.get(id=2)#获取从表B的字段值
A_n = B_n.a.A_name#根据关联字段查询主表的对象,后缀属性获取值
反向查询
A_n = A.objects.get(id=2)#获取主表A的字段值
B_n = A_n.b_set.all()#根据关联字段查询从表的对应字段;表名要小写,使用_set方法,后缀可使用查询方法.
- 正向查询获取主表的值是一条记录,使用属性,
- 反向查询获取关联的从表的值是QuerySet,使用_set方法获取对象,所以要使用查询方法,
- 表名小写
多对多查询:
创建model:
class A(models.Model):
A_name = models.ManyToManyField()(
'B'关联表名
)
class B(models.Model):
B_name = models.TextField(
max_length=20,
verbose_name='问题',
null=True,
default="问题限制40个字节"
)
正反的查询是相同的:
#获取B表值,查询A表关联字段
B_n = B.objects.get(id=2)#获取从表B的字段值
A_n = B_n.a.all()#根据关联字段查询主表的对象,后缀方法获取值;
A_n = B_n.a_set.all()#这里有疑问!
tigs:
关联的是表的主键,默认是自增ID,如没有特殊原因不要更换,获取关联的值一般是类设定的主值,和主键是不同的概念.
进阶:
懒加载和缓存
QuertSet创建是不访问数据库的,使用时第一次会访问数据库,后续遍历和切片以及属性都是使用缓存,使用len()/list()/bool()需要重新加载,这里的理解对后续编程影响很大。