django框架——ORM 表操作和表查询

ORM 表操作和表查询

单表操作

# 增
    res = models.User.objects.create(...)
    
    user_obj = models.User(name='egon',age=84)
    user_obj.save()
    
# 删
    res = models.User.objects.filter(pk=2).delete()

    user_obj = models.User.objects.filter(pk=1).first()
    user_obj.delete()

# 改
    models.User.objects.filter(pk=4).update(name='egonDSB')

    user_obj = models.User.objects.filter(pk=6)
    user_obj.name = 'egonPPP'
    user_obj.save()
    
# 查
user_obj = models.User.objects.get(pk=4)
user_obj = models.User.objects.filter(pk=6)

get 直接返回数据对象,数据不存在,报错
filter 返回queryset,要first(),得到对象,不会报错

pk:
        uid
        pid
        sid
        ... 

必知必会13条

all()        查询所有数据
filter()     带有过滤条件的查询
get()        直接拿数据对象 但是条件不存在直接报错
first()      拿queryset里面第一个元素
last()

values()  可以指定获取的数据字段  列表套字典
res = models.User.objects.values('name','age')  
<QuerySet [{'name': 'jason', 'age': 18}, {'name': 'egonPPP', 'age': 84}]>
    
values_list()  列表套元祖
res = models.User.objects.values_list('name','age')  
<QuerySet [('jason', 18), ('egonPPP', 84)]>

distinct()  去重
res = models.User.objects.values('name','age').distinct()
去重一定要是一模一样的数据 如果带有主键 肯定不一样

order_by()
res = models.User.objects.order_by('age')  # 默认升序
res = models.User.objects.order_by('-age')  # 降序

reverse()  反转的前提是 数据已经排过序  order_by()
res = models.User.objects.all()
res1 = models.User.objects.order_by('age').reverse()

count()  统计当前数据的个数
res = models.User.objects.count()

exclude()  排除在外
res = models.User.objects.exclude(name='jason')

exists()
res = models.User.objects.filter(pk=10).exists()

查看内部sql语句的方式

# 方式1

res = models.User.objects.values_list('name','age')  
# <QuerySet [('jason', 18), ('egonPPP', 84)]>
print(res.query)

queryset对象才能够点query查看内部的sql语句


# 方式2:所有的sql语句都能查看

配置文件中配置
LOGGING = {
    'version': 1,
    'disable_existing_loggers': False,
    'handlers': {
        'console':{
            'level':'DEBUG',
            'class':'logging.StreamHandler',
        },
    },
    'loggers': {
        'django.db.backends': {
            'handlers': ['console'],
            'propagate': True,
            'level':'DEBUG',
        },
    }
}

神奇的双下划线查询

    大于
    res = models.User.objects.filter(age__gt=35)
    小于
    res = models.User.objects.filter(age__lt=35)
    大于等于 小于等于
    res = models.User.objects.filter(age__gte=32)
    res = models.User.objects.filter(age__lte=32)


    __in
    res = models.User.objects.filter(age__in=[18,32,40])
    __range 首尾都要
    res = models.User.objects.filter(age__range=[18,40])

    是否包含 模糊查询 区分大小写
    res = models.User.objects.filter(name__contains='s')
    忽略大小写
    res = models.User.objects.filter(name__icontains='p')

    res = models.User.objects.filter(name__startswith='j')
    res1 = models.User.objects.filter(name__endswith='j')

    查询出注册时间是 2020 1月
    res = models.User.objects.filter(register_time__month='1')
    res = models.User.objects.filter(register_time__year='2020')

一对多外键增删改查

    # 增
    # 1  直接写实际字段 id
    models.Book.objects.create(title='论语',price=899.23,publish_id=1)

    # 2  虚拟字段 对象
    publish_obj = models.Publish.objects.filter(pk=2).first()
    models.Book.objects.create(title='红楼梦',price=666.23,publish=publish_obj)

    # 删
    models.Publish.objects.filter(pk=1).delete()  # 级联删除

    # 改
    models.Book.objects.filter(pk=1).update(publish_id=2)
    
    publish_obj = models.Publish.objects.filter(pk=1).first()
    models.Book.objects.filter(pk=1).update(publish=publish_obj)

多对多外键增删改查

增
    book_obj = models.Book.objects.filter(pk=1).first() 
    book_obj.authors.add(2,3)
    book_obj.authors.add(author_obj1,author_obj2)
    
删
    book_obj.authors.remove(1,3)
    book_obj.authors.remove(author_obj,author_obj1)
    
改
    book_obj.authors.set([1,2])
    book_obj.authors.set([3])  

    book_obj.authors.set([author_obj,author_obj1])  

清空
    # 在第三张关系表中清空某个书籍与作者的绑定关系
    book_obj.authors.clear()

正反向查询

从有外键字段的表,查相关表,为正向查询
从没有外键字段的表,查相关的有外键字段的表,为反向查询

正向查询按字段

反向查询按表名小写
_set
.all()

多表查询

子查询(基于对象的跨表查询)

结果多个.all()
结果一个,直接拿到数据对象

反向查询的时候
    结果多个   必须加_set.all()
    结果一个   不加_set.all()

联表查询(基于双下划线的跨表查询)

自身的字段直接写,别的关联表的字段,要 表__字段

联表查询:
在有关联的几张表中,
filter参数,本身表的条件,直接写,其它表的条件要 表__字段  参数不加引号
values参数,本身表的字段,直接写,其他表的字段要 表__字段  参数加引号

    表__字段 拿到字段
    表__外键__字段 拿到间接表的字段

聚合查询 aggregate

from app01 import models
from django.db.models import Max,Min,Sum,Count,Avg

res = models.Book.objects.aggregate(Max('price'),Min('price'),Sum('price'),
                                        Count('pk'),Avg('price'))

分组查询 annotate

分组之后默认只能获取到分组的依据 组内其他字段都无法直接获取

    from django.db.models import Max, Min, Sum, Count, Avg

    res = models.Book.objects.annotate(author_num=Count('authors')).values('title','author_num')
    
    models后面点什么 就是按什么分组
    author_num是我们自己定义的字段


    按照指定的字段分组
        models.Book.objects.values('price').annotate()
    
    如果出现分组查询报错的情况 需要修改数据库严格模式

F与Q查询

# F查询
    
    直接获取表中某个字段对应的数据 可以比较两个字段的大小

    from django.db.models import F
    res = models.Book.objects.filter(maichu__gt=F('kucun'))

    将所有书籍的价格提升500块
    models.Book.objects.update(price=F('price') + 500)


    将所有书的名称后面加上爆款两个字
    
    在操作字符类型的数据的时候 F不能够直接做到字符串的拼接
    
    from django.db.models.functions import Concat
    from django.db.models import Value
    models.Book.objects.update(title=Concat(F('title'), Value('爆款')))
    models.Book.objects.update(title=F('title') + '爆款')  # 所有的名称会全部变成空白
 # Q查询
    
    filter括号内多个参数是and关系
    
    from django.db.models import Q
    res = models.Book.objects.filter(Q(maichu__gt=100),Q(price__lt=600))
    逗号 and关系
    res = models.Book.objects.filter(Q(maichu__gt=100)|Q(price__lt=600))
    | or关系
    res = models.Book.objects.filter(~Q(maichu__gt=100)|Q(price__lt=600))
    ~ not关系

    Q的高阶用法  能够将查询条件的左边变成字符串的形式
    q = Q()
    q.connector = 'or'
    q.children.append(('maichu__gt',100))
    q.children.append(('price__lt',600))
    res = models.Book.objects.filter(q)  # 默认还是and关系
posted @   pythoner_wl  阅读(186)  评论(0编辑  收藏  举报
编辑推荐:
· AI与.NET技术实操系列:基于图像分类模型对图像进行分类
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
阅读排行:
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· 25岁的心里话
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 按钮权限的设计及实现
点击右上角即可分享
微信分享提示