django ORM之CRUD基本、进阶、高阶操作

django的orm是一个十分强大的数据库操作模块,用面对对象的思想为我们重构了sql查询语句,一个类就代表一个表,一个属性就代表一个字段。极大的简化了我们对数据库操作的复杂度。
数据库操作无外乎CRUD这一套操作,即增、查、改、删。
ORM基本的增删改查:
增:

modes.Tb.object.create() # 增加一条数据,可以接受字典(**kwargs)类型的数据

obj = modes.Tb()
obj.save() # 可批量添加数据

查:

models.Tb.objects.get() # 获取单条数据,不存在报错
models.Tb.objects.all() # 获取全部数据
models.Tb.objects.filter() # 获取指定条件的数据,不存在返回None

改:

models.Tb.objects.filter().update() # 将指定条件的数据更新,支持**kwargs
# update更新完保存到数据库不会执行save()方法,因此不会更新auto_now设置的字段
obj = models.Tb.objects.get()
obj.c1 = " "
obj.save()

删:

models.Tb.objects.filter().delete() # 删除指定条件的数据

ORM之进阶操作(双下划线的魅力):
获取个数:

models.Tb.objects.filter().count()

gt(大于),gte(大于等于),lt(小于),lte(小于等于):

id__gt = 1 # 获取id大于1的数据
id__gte = 1 # 获取id大于等于1 的数据
id__lt = 10 # 获取id小于10的数据
id__ite = 10 # 获取id小于等于10的数据
id__lt = 10,id__gt = 1 #获取id大于1且小于10的数据

in:

id__in = [1,2,3] # 获取id等于1,2,3的数据
exclude(id__in = [1,2,3]) # 获取id不等于1,2,3的数据

isnull(是否为空):

id__isnull = True # 获取id为空的数据

contains:

name__contains = "××" # 获取名字包含××的数据
name__icontains = "××" # 同样是获取名字包含××的数据,但对大小写不敏感
exclude(name__icontains = " ××") # 获取名字不包含××的数据

range:

id__range = [1,5] # 获取id在1-5之间的数据,不包括id=5

还有一些其他类似的方法:
startwswith(判断开头),istartswith(不区分大小写),endswith(判断结尾),iendswith(不区分大小写)。
order_by:

filter().order_by("id") # 以id为标准进行正向排序
filter().order_by("-id") # 反向排序

group_by:

filter().values("id").annotate(num_id=Count("id")) # 以id进行分组,并获取每组id的数量命名为num_id

limit(限制个数),offset(偏移量)(切片操作):

models.Tb.objects.all()[10:20] # 获取第10条到第20条之间的数据,不包括第20条

regex(正则匹配):

title__regex = r'^\d+' # 获取标题开头为数字的数据
iregex不区分大小写

ORM之高阶操作:
values:
指定需要提取的字段,默认全部提取,返回的是字段和值组成的字典

objects.values("字段")
# 如果想要更改字段名,可以使用关键字参数
objects.values(new_name = F("字段")) # new_name不可与表中已有名字冲突

在这里插入图片描述
django ORM之CRUD基本、进阶、高阶操作_第1张图片
values中还可以使用聚合函数形成新的字段。
values_list:
同values功能一样,只不过返回的是字段和值组成的元组

objects.values("字段")

在这里插入图片描述
defer:
过滤掉不需要的字段,返回的是queryset对象模型

objects.defer("字段") # 虽然查询时过滤掉该字段,但是使用objects.字段时还是可以获取到,因为它又进行了一次数据库查询。

在这里插入图片描述
only:
与defer相反,获取需要的字段。
get_or_create:
根据条件进行查找,如果找到了就返回,没找到就创建一个再返回,例如我们去获取一个文章的作者时,如果没有就创建一个作者“佚名”并返回。

objects.get_or_create("字段"="值")

在这里插入图片描述
bulk_create:
一次性创建多条数据

objects.bulk_create([表名(字段=“值”),表名(字段=“值”)])

distinct:
去除掉重复数据

objects.filter(过滤条件).distinct()

需要注意的是,如果在distinct之前使用了order_by,那么因为order_by会提取order_by中指定的字段,因此再使用distinct就会根据多个字段来进行唯一化,所以就不会把那些重复的字段删掉。
F:
用来更新获取原来值的,例如F(age)表示原age

filter(id=1).update(F("age")+1) # 对id等于1的数据中的年龄加1

Q:

filter(Q(id=1) | Q(id=2)) # 获取id=1或id=2的数据,“|”表示或
filter(Q(id=1) & Q(id=2)) # 获取id=1和id=2的数据,“&”表示与

# 另一种用法
# q1 里的条件均为or的关系
q1 = Q()
q1.connector = "OR" # 限定关系为or
q1.children.append(("id",1)) # 添加限定条件
q1.children.append(("id",2)) 
# q2里的条件也均为or的关系
q2 = Q()
q2.connector = "OR"
q2.children.append(("age",18))
q2.children.append(("age",19))
# 使用connect通过and的条件将q1和q2联系到一块
connect = Q()
connect.add(q1,"AND")
connect.add(q2,"AND")
# 上面的语句得到的结果就是获取id为1 或 id为2 和 age为18 或 age为19 的数据
# Q用于构造较为复杂的查询条件。

extra:
可以用来执行原生的sql语句

#参数有:select=None, where=None, params=None, tables=None, order_by=None, select_params=None

models.Tb.objects.extra(select={'new_id': "select id from tb where id > %s"}, select_params=(1,), order_by=['-nid'])

还有一种直接执行原生sql的方法:raw()

#参数:raw_query, params=None, translations=None, using=None

models.UserInfo.objects.raw('select * from userinfo')

select_related:
只可用于一对多或一对一关系中

objects.select_related("外键") # 相当于join,进行连表查询,查询时可将相关外键的表中数据一并查出来

prefetch_related:
主要用于多对一或者多对多关系中,也可用于一对一或一对多

objects.prefetch_related("外键_set","外键") # 不做连表,做多次查询

你可能感兴趣的:(django,mysql,ORM)