单表查询
queryset对象就可以无限制的点queryset方法
新增数据
基于Queryset
models.对应表的类名.objects.create(字段名 = 值,……)
基于对象
object = models.对应表的类名(字段名 = 值,……)
object.save()
修改数据
基于Queryset
models.对应表的类名.objects.filter(字段名 = 值[查找条件]).update(字段名=值[更改后的数据])
基于对象
object = models.对应表的类名.objects.filter(字段名 = 值[查找条件]).first()
object.字段名 = 值
object.save()
删除数据
基于Queryset
models.对应表的类名.objects.filter(字段名 = 值[查找条件]).delete()
基于对象
object = models.对应表的类名.objects.filter(字段名 = 值[查找条件]).first()
object.delete()
查询数据
1.all()
: 查询所有结果
2.filter(**kwargs)
: 它包含了与所给筛选条件相匹配的对象,filter内可以放多个限制条件,多个条件之间是and关系
3.get(**kwargs)
: 返回与所给筛选条件相匹配的对象,返回结果有且只有一个,如果符合筛选条件的对象超过一个或者没有都会抛出错误。
4.exclude(**kwargs)
: 它包含了与所给筛选条件不匹配的对象
5.order_by(*field)
: 对查询结果排序,默认是以括号里的值升序排列,在值前面加上负号-就是降序排列
6.reverse()
: 对查询结果反向排序,前面要先有排序才能反向
7.count()
: 返回数据库中匹配查询(QuerySet) 的对象数量
8.first()
: 返回第一条记录
9.last()
: 返回最后一条记录
10.exists()
: 如果QuerySet包含数据,就返回True,否则返回False
11.values(*field)
: 返回一个ValueQuerySet——一个特殊的QuerySet,运行后得到的并不是一系列model的实例化对象,而是一个可迭代的字典序列
12.values_list(*field)
: 它与values()非常相似,它返回的是一个元组序列(列表套元祖),values返回的是一个字典序列
13.distinct()
: 从返回结果中剔除重复纪录 去重的对象必须是完全相同的数据才能去重(例如若id不同但其他所有都相同的记录不会被删除,但我们先指定相同的字段,再针对此删除相同的数据)
双划线查询
语法:字段名__查询条件=值
1.__gt=值 :大于……的
2.__gte=值 :大于等于……的
3.__lt=值 :小于……的
4.__lte=值 :小于等于……的
5.__in=[值1,值2,……]:在列表的值中的
6.__range=[x,y] :在x和y范围内的
7.__year=值 :年份
8.__contains=值:包含……的(大小写敏感)
9.__icontains=值:包含……的(大小写不敏感)
10.__startswith=值:以……开头的
11.__endswith=值:以……开头的
多表查询
栗子:
数据库设计
图书表book:id,title,price,publish_date
作者表author:id,name,age
出版社表publish:id,name,addr,email
作者详情表:id,phone,addr
表之间的关系
图书表和作者表是多对多关系
图书表和出版社表是多对一关系
作者表和作者详情表是一对一关系
模型表
class Book(models.Model):
# 主键不指定默认创建id字段为主键
title = models.CharField(max_length=32)
price = models.DecimalField(max_digits=8,decimal_places=2)
publish_date = models.DateField(auto_now_add=True) # auto_now:每次操作改数据都会自动更新时间,auto_now_add:新增数据的时候会将当前时间自动添加,后续的修改该字段不会自动更新
# 外键关系
publish = models.ForeignKey(to='Publish')
authors = models.ManyToManyField(to='Author') # 虚拟字段, 信号字段
def __str__(self):
return '书籍对象的名字:%s'%self.title
class Publish(models.Model):
name = models.CharField(max_length=32)
addr = models.CharField(max_length=32)
email = models.EmailField() # 对应就是varchar类型
def __str__(self):
return '出版社对象的名字:%s'%self.name
class Author(models.Model):
name = models.CharField(max_length=32)
age = models.IntegerField()
authordetail = models.OneToOneField(to='AuthorDetail')
def __str__(self):
return '作者对象的名字:%s'%self.name
class AuthorDetail(models.Model):
phone = models.CharField(max_length=32)
addr = models.CharField(max_length=32)
为外键关系字段赋值
1.直接写数据:publish_id=1
models.Book.objects.create(title='红楼梦',price=66.66,publish_id=1)
2.传数据对象:publish=publish_obj
publish_obj = models.Publish.objects.filter(pk=2).first()
models.Book.objects.create(title='三国演义',price=199.99,publish=publish_obj)
表与表之间添加关系
add:支持传数字或对象,并且都可以传多个
表1_object = models.对应表1的类名.objects.filter(字段名 = 值[查找条件]).first()
表1_object.与表2的关联字段.add(数字或表2对象)
表与表之间修改关系
set:传的必须是可迭代对象(用元祖形式)
表1_object = models.对应表1的类名.objects.filter(字段名 = 值[查找条件]).first()
表1_object.与表2的关联字段.set((数字,)或表2对象)
表与表之间删除关系
remove:需要将queryset打散,*<queryset>
表1_object = models.对应表1的类名.objects.filter(字段名 = 值[查找条件]).first()
表1_object.与表2的关联字段.remove((数字,)或打散的表2对象)
清空表与表之间的关系
clear():清空的是你当前这个表记录对应的绑定关系
表1_object = models.对应表1的类名.objects.filter(字段名 = 值[查找条件]).first()
表1_object.与表2的关联字段.clear()
基于对象的表查询
正向查询与反向查询:正向查询按字段,反向查询按表名小写
判断正向查询与反向查询的依据是关联字段是否在表内
正向
表1_object = models.对应表1的类名.objects.filter(字段名 = 值[查找条件]).first()
表1_object.与表2的关联字段[.all()].表2字段
反向
表2_object = models.对应表2的类名.objects.filter(字段名 = 值[查找条件]).first()
表2_object.与表1名小写_set[.all()].表1字段
多对一关系和多对多关系如果不加.all()
会显示项目名.对应表的类名.None
,因为对应关系查出来的结果会多于一个,而一对一关系则不需要加。
基于双下滑线的查询
正向
models.对应表1的类名.objects.filter(字段名 = 值[查找条件]).value(与表2关系字段__查询的字段名)
反向
models.对应表2的类名.objects.filter(字段名 = 值[查找条件]).value(对应表1的类名小写__查询的字段名)
聚合查询aggregate
导入聚合函数from django.db.models import Max,Min,Count,Sum,Avg
models.对应表的类名.objects.filter(字段名 = 值[查找条件]).aggregate(别名=聚合函数(字段名[双下划线查询适用]))
分组查询annotate
models.对应表的类名.objects.annotate(别名=聚合函数(字段名[双下划线查询适用])).values(分组字段,别名)