Django之ORM单表操作

我们以上篇文章创建的数据表进行以下操作,models.py代码如下:

from django.db import models

class UserGroup(models.Model):
    """部门"""
    department = models.CharField(max_length=32)

class UserInfo(models.Model):
    """员工"""
    uid = models.AutoField(primary_key=True)            # 若无指定,Django为默认生成以id命名的一列自增数据
    username = models.CharField(max_length=32)          # 必须指定长度
    password = models.CharField(max_length=64)
    age = models.IntegerField(default=1)
    ug = models.ForeignKey("UserGroup",on_delete=models.CASCADE,)       # 生成数据库后,列名称变更为ug_‘外键表的id’

ORM使用方式:

  • 使用类实例化,即obj.save()的方式
  • 使用create()的形式

一 增

# 方式一:利用create(),create方法的返回值dpart_obj就是插入department表中的“人力资源部”这条记录对象
dpart_obj = models.UserGroup.objects.create(department = '人力资源部')
# 方式二:利用类实例化:obj = models.类(属性=xx) obj.save()
obj = models.UserGroup(department = '研发部')
obj.save()
# 方式三:利用bulk_create()一次性添加多条数据
objs = [
	models.UserGroup(department='设备部'),
	models.UserGroup(department='财务部'),
	models.UserGroup(department='战略部'),
]
models.UserGroup.objects.bulk_create(objs,5)
# 方式四:通过字典一次性增加数据  *****
dic={'k1':'v1','k2':'v2',...}  # key指相对应表的字段名称
models.xx.objects.create(**dic)

二 删

删除采用delete(),它运行时会立即删除对象而不会返回任何值

models.UserGroup.objects.filter(id=2).delete()

每个 QuerySet 都有一个 delete() 方法,它可以一次性删除 QuerySet 中所有的对象。

models.UserGroup.objects.all().delete()

注意点:

1.无论在什么情况下,QuerySet 中的 delete() 方法都只使用一条 SQL 语句一次性删除所有对象,并不是分别删除每个对象

DELETE FROM "app01_userinfo" WHERE "app01_userinfo"."ug_id" IN (8, 5, 6, 7);

2.删除对象时,会模仿 SQL 约束 ON DELETE CASCADE 的行为,换句话说,删除一个对象时也会删除与它相关联的外键对象(默认)

delete_num = models.UserGroup.objects.filter(id__gt=14).delete()
print(delete_num)    #(5, {'app01.UserInfo': 3, 'app01.UserGroup': 2})

3.delete() 方法是 QuerySet 上的方法,但并不适用于 Manager 本身。这是一种保护机制,是为了避免意外地调用 models.xxx.objects.delete() 方法导致所有的记录被误删除。如果你确认要删除所有的对象,那么你必须显式地调用:

models.xxx.objects.all().delete() 

如果不想级联删除,可以设置为:

ug = models.ForeignKey("UserGroup", on_delete=models.SET_NULL, null=True) 

三 改

# 方式一:利用update()
models.UserGroup.objects.filter(id=7).update(department = '人力资源部111')
# 方式二:利用类实例化
obj = models.UserGroup.objects.get(id=8)
print(obj)        # UserGroup object (8)
obj.department = '财务部111'
obj.save()
# 方式三:通过字典一次性更改数据
dic = {'k1':'v1','k2':'v2',...}
models.xx.objects.filter(id=1).update(**dic)

 注意点:

1.第一种方式修改不能用get的原因是:update是QuerySet对象的方法,get返回的是一个model对象,它没有update方法,而filter返回的是一个QuerySet对象。

# Queryset对象
<QuerySet [<UserGroup: UserGroup object>]>
# model对象
UserGroup object

更多不返回QuerySets的API可参考:http://www.liujiangblog.com/course/django/131

2.update()方法对于任何结果集(QuerySet)均有效,这意味着我们可以同时更新多条记录,同时,update()方法会返回一个整型数值,表示受影响的记录条数。

update_num = models.UserGroup.objects.filter(id__gt=12).update(department = 'IT部')
print(update_num)    # 2

四 查

4.1 基本操作

# 1.all():查询所有
obj1 = models.UserInfo.objects.all()
print(obj1)          # <QuerySet [<UserInfo: UserInfo object (14)>, <UserInfo: UserInfo object (17)>, ...]>

# 2.filter():查询不到不会报错。可以实现且关系,或关系需要借助Q查询实现,条件可以是:参数、字典、Q
obj2 = models.UserInfo.objects.filter(username="张三1")          # 查询名字为张三1的数据
obj3 = models.UserInfo.objects.filter(username="张三1", age=18)  # 查询名字为张三1并且年龄为18的数据
# 多个条件时,我们可以组合成字典进行查询
dic={'k1':'v1','k2':'v2',...}  ********
models.xx.objects.filter(**dic)
print(obj2)          # <QuerySet [<UserInfo: UserInfo object (17)>]>
print(obj3)          # <QuerySet []>

# 3.get():查询不到会报错,如果有多个值,也会报错,只能拿有一个值的
obj4 = models.UserInfo.objects.get(username="张三1")
print(obj4)          # UserInfo object (17)

# 4.first(): 取第一个值
obj5 = models.UserInfo.objects.all().first()
print(obj5)          # UserInfo object (14)

# 5.last():取最后一个值
obj6 = models.UserInfo.objects.all().last()
print(obj6)          # UserInfo object (20)

# 6.values():QuerySet的一个方法(把对象转换成字典)
obj7 = models.UserInfo.objects.filter(username="张三1").values("uid", "password")  # 查看名字为张三1的id和密码
print(obj7)          # <QuerySet [{'uid': 17, 'password': '123'}]>

# 7.values_list():queryset的一个方法(把对象转成元组)
obj8 = models.UserInfo.objects.filter(username="张三1").values_list("uid", "password")
print(obj8)          # <QuerySet [(17, '123')]>

# 8.exclude():排除条件,条件可以是参数、字典、Q
obj9 = models.UserInfo.objects.exclude(username="张三1")    # 查询除了名字是张三一的数据
print(obj9)          # <QuerySet [<UserInfo: UserInfo object (14)>, <UserInfo: UserInfo object (18)>, ...]>

# 9.order_by():排序
obj10 = models.UserInfo.objects.all().order_by("age")
obj11 = models.UserInfo.objects.all().order_by("-age")
models.UserInfo.objects.all().order_by("age,username")     # 先以age再以username排序
print(obj10)         # <QuerySet [<UserInfo: UserInfo object (14)>, <UserInfo: UserInfo object (19)>, ...]>
print(obj11)         # <QuerySet [<UserInfo: UserInfo object (20)>, <UserInfo: UserInfo object (17)>, ...]>

# 10.annotate:用于实现聚合group by查询
from django.db.models import Count, Min, Max, Sum
obj12 =  models.UserInfo.objects.filter(age=18).values('username').annotate(xxx=Count('uid'))
print(obj12)         # <QuerySet [{'xxx': 1, 'username': '张三2'}, {'xxx': 2, 'username': '张三3'}]>
SELECT "app01_userinfo"."username", COUNT("app01_userinfo"."uid") AS "xxx" FROM "app01_userinfo" WHERE" app01_userinfo"."age" = 18
GROUP BY "app01_userinfo"."username" LIMIT21;

# 11.reverse():倒序
obj13 = models.UserInfo.objects.all().reverse()
print(obj13)         # <QuerySet [<UserInfo: UserInfo object (14)>, <UserInfo: UserInfo object (17)>, ...]>

# 12.distinct():去重(只要结果里面有重复的)
obj14 = models.UserInfo.objects.filter(age=18).values("username").distinct()
print(obj14)         # <QuerySet [{'username': '张三2'}, {'username': '张三4'}]>

# 13.count():查看有几条记录
obj15 = models.UserInfo.objects.filter(username="张三1").count()
print(obj15)         # 1

# 14.exists():查看有没有记录,如果有返回True,没有返回False,并不需要判断所有的数据
a = models.UserInfo.objects.all().exists()
print(a)             # True

4.2 进阶操作(关键字”--”)

# 1.大于/小于
models.UserInfo.objects.filter(uid__gt=1)                # 获取id大于1的值
models.UserInfo.objects.filter(uid__gte=1)               # 获取id大于等于1的值
models.UserInfo.objects.filter(uid__lt=10)               # 获取id小于10的值
models.UserInfo.objects.filter(uid__lte=10)              # 获取id小于10的值
models.UserInfo.objects.filter(uid__lt=10, uid__gt=1)    # 获取id大于1且小于10的值

# 2.in
models.UserInfo.objects.filter(uid__in=[1, 2, 3])     	 # 获取uid等于1、2、3的数据
models.UserInfo.objects.exclude(uid__in= [1, 2, 3])      # not in

# 3.contains/icontains大小写不敏感
models.UserInfo.objects.filter(username__contains="张三")
models.UserInfo.objects.filter(username__icontains="张三")  
models.UserInfo.objects.exclude(username__contains="张三")

# 4.startswith,istartswith, endswith, iendswith
models.UserInfo.objects.filter(username__startswith = "张")
models.UserInfo.objects.filter(username__endswith = "3")

# 5.range
models.UserInfo.objects.filter(uid__range=[14, 18])      # 范围bettwen and,前后都包含

# 6.regex正则匹配,iregex不区分大小写
models.UserInfo.objects.filter(username__regex=r'abc')
models.UserInfo.objects.filter(username__iregex=r'abc')

# 7.isnull
models.UserInfo.objects.filter(username__isnull=True)

# 8.limit 、offset
models.UserInfo.objects.all()[1:2]     #顾头不顾尾

 

其他操作可参考:http://www.cnblogs.com/wupeiqi/articles/6216618.html

posted @ 2018-09-28 16:34  Joe1991  阅读(183)  评论(0)    收藏  举报