• ORM数据库操作


    ORM操作关键字

            ORM就是为了让不会数据库操作的python程序员也能够操作数据库处理数据,而处理数据无非就是对数据的增、删、改、查,因此ORM给我们提供了各种操作数据的关键字

             先创建一张表用于举例

    1. class User(models.Model):
    2. uid = models.AutoField(primary_key=True, verbose_name='编号')
    3. name = models.CharField(max_length=32, verbose_name='姓名')
    4. age = models.IntegerField(verbose_name='年龄')
    5. join_time = models.DateField(auto_now_add=True)

    1.模型层测试环境准备

            方式一:在任意空的py文件中准备环境

    1. import os
    2. def main():
    3. os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'day59.settings')
    4. import django
    5. django.setup()
    6. if __name__ == '__main__':
    7. main()

    2.常见关键字

    create():创建数据 返回值就是当前创建的数据对象

    update():更新数据

    delete():删除数据

    1. '添加数据'
    2. models.User.objects.create('小明','18')
    3. models.User.objects.create('小强','26')
    4. models.User.objects.create('小红','38')
    5. models.User.objects.create('小兰','66')
    6. '修改id为2的年龄'
    7. models.User.objects.filter(pk=2).update(age=88)
    8. '删除id为3的数据'
    9. models.User.objects.filter(pk=3).delete()

    常见的13个查询关键字:

    filter():返回值是一个QuerySet(可以看成是列表套数据对象)

    1. res = models.User.objects.filter(name='小明', age=18)
    2. '''
    3. 括号内可以填写多个条件 逗号分开默认是and关系
    4. 括号内不写查询条件 默认查询所有
    5. '''

    all():查询所有数据 返回值是一个QuerySet(可以看成是列表套数据对象)

    1. res = models.User.objects.all()
    2. print(res[1])
    3. for i in res:
    4. print(i)
    5. '''
    6. 可以索引获取每个数据对象
    7. 也可以用for循环获取
    8. '''

    first():获取Queryset中第一个数据对象 如果是空则返回None

    1. res = models.User.objects.filter(name="小明").first()
    2. print(res)

    last():获取Queryset中最后一个数据对象 如果是空则返回None

    1. res = models.User.objects.filter(name="小明").last()
    2. print(res)

    get():直接根据条件查询具体的数据对象  如果条件不存在直接报错(不推荐使用)

    1. res = models.User.objects.get(pk=999)
    2. print(res)
    3. '''
    4. 显然没有id为999的值所以会直接报错
    5. 更推荐下面这种方式
    6. '''
    7. res = models.User.objects.filter(pk=999).first()
    8. print(res)
    9. # 不存在返回None

    values():指定查询字段 结果是Queryset(可以看成是列表套字典数据)

    1. res = models.User.objects.all().values('name', 'age')
    2. print(res)
    3. '''
    4. 获取别中所有数据的'name','age'字段数据
    5. '''

    values_list():指定查询字段 结果是Queryset(可以看成是列表套元组数据)

    1. res = models.User.objects.values_list('name','join_time')
    2. print(res)

    order_by():指定字段排序 默认是升序 在字段前加负号则为降序 并且支持多个字段排序

    1. res = models.User.objects.order_by('age') # 按年龄升序
    2. res = models.User.objects.order_by('-age') # 按年龄降序
    3. res = models.User.objects.order_by('age','-join_time')
    4. # 先按年龄升序有相同的年龄再按创建时间降序

    count():统计ORM查询之后结果集中的数据格式

    res = models.User.object.all().count()

    distinct():针对重复的数据进行去重 (注意数据对象中的主键)

    1. res = models.User.objects.values('name','join_time').distinct()
    2. print(res)
    3. '''
    4. 避免主键因为主键肯定是不重复的数据
    5. '''

    exclude():针对括号内的条件取反进行数据查询(QuerySet可以看成是列表套数据对象)

    1. res = models.User.objects.exclude(pk=1)
    2. print(res)
    3. '''
    4. 查询除id是1以为的所有数据
    5. '''

    reverse():针对已经排序了的结果集做颠倒

    1. res = models.User.objects.all().order_by('age').reverse()
    2. print(res)
    3. '''
    4. 将按年龄升序完后的数据再取个反,倒叙一下
    5. '''

    existe():判断查询结果是否有数据, 返回布尔值(几乎所有数据都已自带布尔值了)

    1. res = models.User.objects.filter(pk=999).exists()
    2. print(res)
    3. '''
    4. 判断查询结果 True/False
    5. '''

    raw():执行SQL语句

    1. res = models.User.objects.raw('select * from app01_user')
    2. print(res)
    3. '''
    4. 注意要用生成的app01_user表
    5. 也可以用另一种方法:在配置文件中加
    6. from django.db import connection
    7. cursor = connection.cursor()
    8. cursor.execute("insert into hello_author(name) VALUES ('郭敬明')")
    9. cursor.execute("update hello_author set name='韩寒' WHERE name='郭敬明'")
    10. cursor.execute("delete from hello_author where name='韩寒'")
    11. cursor.execute("select * from hello_author")
    12. cursor.fetchone()
    13. cursor.fetchall()
    14. '''

    双下划线查询

    1.比较运算符

    1. '''
    2. 字段__gt 大于
    3. 字段__lt 小于
    4. 字段__gte 大于等于
    5. 字段__lte 小于等于
    6. '''
    7. # 举例:
    8. res = models.User.objects.filter(age__gt=20)
    9. # 查询年龄大于20的数据,换成__gte则是查询小于等于
    10. res1 = models.User.objects.fileter(age__lt=20)
    11. # 查询年龄小于20的数据,换成__lte则是查询小于等于

    2.日期处理

    1. '''
    2. 字段__year 年
    3. 字段__month 月
    4. 字段__day 日
    5. '''
    6. res = models.User.objects.filter(join_time__year=2022)
    7. # 查询创建年份是2022年的数据
    8. res = models.User.objects.filter(join_time__month=9)
    9. # 查询创建月份是9月的数据
    10. res = models.User.objects.filter(join_time__day=5)
    11. # 查询创建日子是5号的数据

    3.其它补充

    1. '''
    2. 字段__in 在什么里
    3. 字段__range 数字范围
    4. 字段__contains 模糊查询(不忽略大小写)
    5. 字段__icontains 模糊查询(忽略大小写)
    6. '''
    7. # 举例
    8. res = models.User.objects.filter(name__in =['小明','小兰'])
    9. # 查询姓名是小明或者小兰的数据
    10. res = models.User.objects.filter(age__range=(38, 88))
    11. # 查询年龄在38到88之间的数据(包含首尾)
    12. res = models.User.objects.filter(name__icontains='H')
    13. # 查询名字中带有字母H的忽略大小写包含h的也行
    14. res = models.User.objects.filter(name__contains='H')
    15. # 查询名字中带有字母H只能是大写字母H

    ORM底层SQL查看

    方式一:

            如果结果是Queryset对象 那么可以直接点query查看SQL语句

    方式二:

            在配置文件里配置 打印所有的ORM操作对应的SQL语句

    1. LOGGING = {
    2. 'version': 1,
    3. 'disable_existing_loggers': False,
    4. 'handlers': {
    5. 'console':{
    6. 'level':'DEBUG',
    7. 'class':'logging.StreamHandler',
    8. },
    9. },
    10. 'loggers': {
    11. 'django.db.backends': {
    12. 'handlers': ['console'],
    13. 'propagate': True,
    14. 'level':'DEBUG',
    15. },
    16. }
    17. }

    ORM创建外键关系

    1.一对多

            ORM中外键字段建在多的一方  会自动添加_id后缀

    models.ForeignKey()
    

    2.多对多

            ORM中有三种创建多对多字段多方式   

    1. models.ManyToManyField()
    2. '''
    3. 方式1:直接在查询频率较高的表中填写字段即可 自动创建第三张关系表
    4. 方式2:自己创建第三张关系表
    5. 方式3:自己创建第三张关系表 但是还是要ORM多对多字段做关联
    6. '''

    3.一对一

            ORM中外键字段建在查询频率较高的表中 自动添加__id后缀

    models.OneToOneField()
    

    django1.x 针对 models.ForeignKey() 、models.OneToOneField() 不需要on_delete

    django2.x 3.x 则需要添加on_delete参数

    4.创建表格

    1. class Book(models.Model):
    2. title = models.CharField(max_length=32)
    3. price = models.DecimalField(max_digits=8, decimal_places=2) # 总共八位 小数点后面站两位
    4. publish_time = models.DateTimeField(auto_now=True)
    5. publish = models.ForeignKey(to='Publish', on_delete=models.CASCADE)
    6. authors = models.ManyToManyField(to='Author')
    7. def __str__(self):
    8. return '书籍对象:%s' % self.title
    9. class Publish(models.Model):
    10. name = models.CharField(max_length=32)
    11. email = models.EmailField()
    12. def __str__(self):
    13. return '出版社对象:%s' % self.name
    14. class Author(models.Model):
    15. name = models.CharField(max_length=32)
    16. age = models.IntegerField()
    17. author_detail = models.OneToOneField(to='AuthorDetail', on_delete=models.CASCADE)
    18. def __str__(self):
    19. return '作者对象:%s' % self.name
    20. class AuthorDetail(models.Model):
    21. phone = models.BigIntegerField()
    22. addr = models.CharField(max_length=255)
    23. def __str__(self):
    24. return '作者详情对象:%s' % str(self.phone)

    4.2.外键字段数据操作

    1. models.ForeignKey?(to='Publish', on_delete=models.CASCADE)
    2. '''
    3. 方式一:直接给实际字典添加关联数据值 publish_id = 1
    4. 方式二:间接使用外键虚拟字段添加数据对象 publish = publish_obj
    5. '''
    6. models.OneToOneField(to='AuthorDetail', on_delete=models.CASCADE)
    7. '''
    8. 方式一:直接给实际字段添加关联数据值 author_detail_id = 1
    9. 方式二:间接使用外键虚拟字段添加数据对象 author_detail = authorDetail_obj
    10. '''
    11. models.ManyToManyField(to='Author')

    add():添加数据 括号内可以填写数字值也可以填写数据对象 支持多个

    remove():删除数据 括号内即可以填写数字值也可以填写数据对象 支持多个

    set():修改数据 括号内必须是可迭代对象

    clear():清空指定数据 括号内不需要任何参数

    ORM多表查询

    1.正反向概念

            正反向的概念核心在于外键字段在谁手上

    正向查询

            通过书查询出版社 外键字段在书表中

    反向查询

            通过出版社查询书 外键字段不在出版社表中

    ps:ORM多表查询口诀>>>:正向查询按外键字段 反向查询按表名小写(_set)

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

    举例题目理解正向查询与反向查询

    1. # 查询主键为1的书籍对应的出版社
    2. '''
    3. 1.1 先根据条件查询数据对象
    4. 1.2 以对象为基准 考虑是正向还是反向 在通过口诀(正向)
    5. '''
    6. book_obj = models.Book.objects.filter(pk=1).first()
    7. print(book_obj.publish)
    8. # 查询出版社出版的书籍
    9. '''
    10. 2.1 先根据条件查询数据对象
    11. 2.2 一样思考是正向还是反向 再给予口诀(反向)
    12. '''
    13. publish_obj = models.Publish.objects.filter(name ='出版社')
    14. print(publish_obj.book_set.all())

    ps:反向查询时表名小写后还需加(_set)此时获取到的是 app01.Book.None 所以还要加上all()

    3.基于双下划线的跨表查询(连表操作)

    举例题目理解基于双下划线的正向查询与反向查询

    1. # 查询主键为1的书籍对应的出版社及书名
    2. '''
    3. 1.1 根据条件查询数据对象
    4. 1.2 以对象为基准加关键字 values获取另一张表数据 (正向)
    5. '''
    6. res = models.Book.objects.filter(pk=1).values('publish__name','title')
    7. # 查询出版社出版的书籍名称和价格
    8. '''
    9. 2.1 根据条件查询数据对象
    10. 2.2 以对象为基准加关键字 values获取另一张表数据 (反向)
    11. '''
    12. res = models.Publish.objects.filter(name='出版社').values('book_title','book_price')
  • 相关阅读:
    Yolov5 ONNX导出报错: export failure: Unsupported ONNX opset version: 17
    2022广西师范大学暑期训练赛 E ,K
    YOLOv8改进实战 | 更换主干网络Backbone之2023最新模型LSKNet,旋转目标检测SOTA
    基于启发式搜索的一字棋
    TiDB Lightning 命令行参数
    第1章 并发编程的挑战
    JDBC入门、数据库连接方式
    【博客系统】 二
    理解CSS | 青训营笔记
    【Spring】Spring中的DI(依赖注入)Dependence Import
  • 原文地址:https://blog.csdn.net/weixin_52596593/article/details/126707120