首页 > 其他分享 >ORM、ORM操作与查询

ORM、ORM操作与查询

时间:2022-09-05 23:27:22浏览次数:56  
标签:objects User1 models res 查询 ORM print 操作

ORM操作与查询

数据准备及环境测试

1.django有一个自带的sqlite3数据库
该数据库功能非常有限,并且针对日期类型的数据兼容性很差

2.django切换MySQL数据
2.1django1.X
import pymysql
pymysql.install_as_MySQLdb()
2.2django2.X 3.X 4.X
pip install mysqlclient

3.定义模型类
class User1(models.Model):
    uid = models.AutoField(primary_key=True, verbose_name='编号')
    name = models.CharField(max_length=32, verbose_name='姓名')
    age = models.IntegerField(verbose_name='年龄')
    join_time = models.DateTimeField(auto_now_add=True)
    '''
    auto_now:每次操作数据并保存都会自动更新时间
    auto_add:在创建数据时自动获取当前时间
    '''

4.数据库迁移命令
makemigrations
migrate

5.在模型层测试环境准备
方式1:在任意空的py文件中准备环境
'从manage.py中复制一段'
import os
import sys


def main():
    os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'django01.settings')
    import django
    django.setup()
    from app01 import models
    # print(models.User1.objects.filter())
    # <QuerySet [<User1: User1 object (1)>]>


if __name__ == '__main__':
    main()
方式2:pycharm提供测试环境
 python console命令行测试环境

ORM操作关键字

1.create()
res = models.User1.objects.create(name='barry', age=18)
print(res)
# User1 object (1)
'创造数据,返回值就是当前创建的数据对象'
res = models.User1.objects.create(name='tom', age=25)
print(res.name)
# tom
print(res.age)
# 25
print(res.uid)
# 2
print(res.pk)  # 不需要知道主键字段的名字,可以通过pk直接获取
# 2
user_obj = models.User1(name='jerry', age=28)
user_obj.save()
'也可以用实例化对象任何调用save方法创建'

2.在模型类中可以定义一个__str__方法,让后续数据查询更方便查看
def __str__(self):
    '对象执行打印展示(print、页面展示、数据查询)的时候自动触发'
    return f'对象:{self.name}'  # 该方法必须返回一个字符串
'Queryset中如果是列表套对象那么直接for循环和索引取值,不过索引取值不支持负数'

双下划线查询

1.filter()
res = models.User1.objects.filter()
'筛选数据,返回值是一个QuerySet,可以看成是列表套数据对象'
print(res)
# <QuerySet [<User1: User1 object (1)>, <User1: User1 object (2)>, <User1: User1 object (3)>]>
res = models.User1.objects.filter(name='barry')
'括号内不写查询条件则默认查询所有,括号内填写条件,并且支持多个,用逗号隔开,默认是and关系'
print(res)
# <QuerySet [<User1: User1 object (1)>]>

2.all()
res = models.User1.objects.all()
'查询所有数据,返回值是一个QuerySet,可以看成是列表套数据对象'
print(res)
# <QuerySet [<User1: User1 object (1)>, <User1: User1 object (2)>, <User1: User1 object (3)>]>

3.first()
res = models.User1.objects.filter(name='barry')
'可以使用索引,但如果值不存在会报错,所以不推荐'
print(res[0])
# User1 object (1)
res = models.User1.objects.filter().first()
'获取QuerySet中第一个数据,如果值不存在会打印None,所以推荐使用'
print(res)
# User1 object (1)

4.last()
res = models.User1.objects.filter().last()
'获取QuerySet中最后一个数据'
print(res)
# User1 object (3)

5.get()
res = models.User1.objects.get(pk=1)
'根据条件查询具体的数据对象,当条件不存在时直接报错,不推荐使用'
print(res)
# User1 object (1)

6.values()
res = models.User1.objects.all().values('name')
'指定查询字段,结果是一个QuerySet,可以看成是列表套数据对象'
print(res)
# <QuerySet [{'name': 'barry'}, {'name': 'tom'}, {'name': 'jerry'}]>

7.values_list()
res = models.User1.objects.values_list('name')
'指定查询字段,结果是一个QuerySet,可以看成是列表套数据对象'
print(res)
# <QuerySet [('barry',), ('tom',), ('jerry',)]>

8.order_by()
res = models.User1.objects.order_by('age')  # 升序排列
print(res)
# <QuerySet [<User1: User1 object (1)>, <User1: User1 object (2)>, <User1: User1 object (3)>]>
res = models.User1.objects.order_by('-age')  # 降序排序
print(res)
# <QuerySet [<User1: User1 object (3)>, <User1: User1 object (2)>, <User1: User1 object (1)>]>

9.count()
res = models.User1.objects.all().count()
'统计orm查询之后结果集中的数据格式'
print(res)
# 3

10.distinct()
user_obj = models.User1(name='barry', age=22)
res = models.User1.objects.values('name').distinct()
'对数据重复的数据进行去重,只有重复数据才能去重'
print(res)
# <QuerySet [{'name': 'barry'}, {'name': 'tom'}, {'name': 'jerry'}]>

11.exclude()
res = models.User1.objects.exclude(pk=1)
'对括号内的条件取反进行数据查询,结果是一个QuerySet,可以看成是列表套数据对象'
print(res)
# <QuerySet [<User1: User1 object (2)>, <User1: User1 object (3)>, <User1: User1 object (4)>]>

12.reverse()
res = models.User1.objects.all().order_by('age').reverse()
'对已经排序的结果集做颠倒'
print(res)
# <QuerySet [<User1: User1 object (3)>, <User1: User1 object (2)>, <User1: User1 object (4)>, <User1: User1 object (1)>]>

13.exists()
res = models.User1.objects.exists()
'判断查询结果是否有数据值,返回布尔值'
print(res)
# True

14.raw()
'执行SQL语句,还可以借助模块'
from django.db import connection  
cursor = connection.cursor()  
cursor.execute("insert into hello_author(name) VALUES ('barry')") 
cursor.execute("update hello_author set name='tom' WHERE name='barry'")  
cursor.execute("delete from hello_author where name='tom'")  
cursor.execute("select * from hello_author")  
cursor.fetchone()  
cursor.fetchall()

ORM底层SQL查询方式

1.比较运算符
res = models.User1.objects.filter(age__gt=25)  # 大于
print(res)  # <QuerySet [<User1: 对象:jerry>]>
res = models.User1.objects.filter(age__lt=25)  # 小于
print(res)  # <QuerySet [<User1: 对象:barry>, <User1: 对象:barry>]>
res = models.User1.objects.filter(age__gte=25)  # 大于等于
print(res)  # <QuerySet [<User1: 对象:tom>, <User1: 对象:jerry>]>
res = models.User1.objects.filter(age__lte=25)  # 小于等于
print(res)  # <QuerySet [<User1: 对象:barry>, <User1: 对象:tom>, <User1: 对象:barry>]>

2.成员运算符
res = models.User1.objects.filter(name__in=['barry'])  # 匹配返回要求的
print(res)  # <QuerySet [<User1: 对象:barry>, <User1: 对象:barry>]>

3.范围查询(数字)
res = models.User1.objects.filter(age__range=(22, 25))  # 顾头也顾尾
print(res)  # <QuerySet [<User1: 对象:tom>, <User1: 对象:barry>]>

4.模糊查询
res = models.User1.objects.filter(name__contains='r')  # 不忽略大小写
print(res)  # <QuerySet [<User1: 对象:barry>, <User1: 对象:jerry>, <User1: 对象:barry>]>
res = models.User1.objects.filter(name__icontains='R')  # 忽略大小写
print(res)  # <QuerySet [<User1: 对象:barry>, <User1: 对象:jerry>, <User1: 对象:barry>]>

5.日期处理
res = models.User1.objects.filter(join_time__year=2020)  # 匹配返回年份的
print(res)  # <QuerySet [<User1: 对象:jerry>]>
res = models.User1.objects.filter(join_time__month=8)  # 匹配返回月份
print(res)  # <QuerySet [<User1: 对象:jerry>]>
res = models.User1.objects.filter(join_time__day=6)  # 匹配符合日期
print(res)  # <QuerySet [<User1: 对象:jerry>]>

查看ORM底层SQL语句

1.方法1
如果是Queryset对象,可以直接.query查看SQL语句

2.方法2
配置文件配置,打印所有的ORM操作对应的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',
                },
            }
        }

ORM键操作与查询

ORM创建外键创建

1.一对多
ORM中外键字段建在多的一方models.ForeignKey()
'会自动添加_id后缀'

2.多对多
ORM中有三种创建多对多表的方法models.ManyToManyField()
方式1:直接在查询频率高的表中填写自动,自动创建第三张表
方式2:直接创建第三张关系表
方式32:直接创建第三张关系表,但是还是还要orm多对多字段做关联

3.一对一
ORM中外键字段建在查询频率较高的表中,models.OneToOneField()
'会自动添加_id后缀'

'django1.X 针对 models.ForeignKey() models.OneToOneField()不需要on_delete,django2.X 3.X 则需要添加on_delete参数'

外键字段的数据操作

1.一对多添加数据
1.1方式1直接给实际字段添加关联数据值
models.Book.objects.create(title='django基础', price=19000.98, publish_id=1)
1.2方式2间接使用外键虚拟字段添加数据对象
publish_obj = models.Publish.objects.filter(pk=2).first()
models.Book.objects.create(title='Golang高并发', price=19800.98, publish=publish_obj)

2.一对一添加数据
1.1方式1直接给实际字段添加关联数据值
author_detail_id = 1
1.2方式2间接使用外键虚拟字段添加数据对象
publish_obj = models.Publish.objects.filter(pk=2).first()
author_detail=authorDetail_obj
models.ManyToManyField(to='Author')

3.多对多添加数据
book_obj = models.Book.objects.filter(pk=1).first()
3.1book_obj.authors.add(1)  # 朝第三张表里面添加数据
添加数据,括号内即可以填写数字值也可以填写数据对象,支持多个

3.2book_obj.authors.remove(1)  # 朝第三张表里面删除数据
删除数据,括号内即可以填写数字值也可以填写数据对象,支持多个

3.2book_obj.authors.set([2, ])
修改数据,括号内必须是可迭代对象,支持多个

3.3book_obj.authors.clear()
清空指定数据,括号内不需要任何参数

正反向概念

'正反向的概念核心就在于外键字段在谁手上'
1.正向查询
通过拥有外键字段的表查询没有外键字段的表,叫正向查询

2.反向查询
通过没有外键字段的表查询有外键字段的表,叫反向查询

RM跨表查询>>>:正向查询按外键字段,反向查询按表名小写

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

'基于对象的正向跨表查询'
1.查询主键为1的书籍对应的出版社(书>>>出版社)
 1.1.先根据条件查询数据对象(先查书籍对象)
book_obj = models.Book.objects.filter(pk=1).first()
1.2.以对象为基准,思考正反向概念(书查出版社,外键字段在书表中,所以是正向查询)
print(book_obj.publish)
# 北方出版社

2.查询主键为2的书籍对应的作者(书>>>作者)
2.1.先根据条件查询数据对象(先查书籍对象)
book_obj = models.Book.objects.filter(pk=2).first()
2.2.以对象为基准,思考正反向概念(书查作者,外键字段在书表中,所以是正向查询)
print(book_obj.authors)
# app01.Author.None
print(book_obj.authors.all())
# <QuerySet [<Author: barry>]>

3.查询jason的作者详情
3.1.先根据条件查询数据对象
author_obj = models.Author.objects.filter(name='barry').first()
3.2.以对象为基准,思考正反向概念
print(author_obj.author_detail)
# 上海

'基于对象的反向跨表查询'
4.查询南方出版社出版的书籍
4.1.先拿出版社对象
publish_obj = models.Publish.objects.filter(name='南方出版社').first()
4.2.思考正反向
print(publish_obj.book_set.all())
# <QuerySet [<Book: Book object (2)>, <Book: Book object (4)>]>

5.查询jason写过的书
5.1.先拿作者对象
author_obj = models.Author.objects.filter(name='barry').first()
5.2.思考正反向
print(author_obj.book_set.all())
# <QuerySet [<Book: Book object (1)>, <Book: Book object (2)>]>

6.查询电话是110的作者
6.1.先拿作者详情对象
author_detail_obj = models.AuthorDetail.objects.filter(phone=110).first()
6.2.思考正反向
print(author_detail_obj.author)
# barry

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

'基于双下划线的正向跨表查询'
1.查询主键为1的书籍对应的出版社名称及书名
res = models.Book.objects.filter(pk=1).values('publish__name', 'title')
print(res)
# <QuerySet [{'publish__name': '北方出版社', 'title': 'django基础'}]>

2.查询主键为3的书籍对应的作者姓名及书名
res = models.Book.objects.filter(pk=2).values('publish__name', 'title')
print(res)
# <QuerySet [{'publish__name': '南方出版社', 'title': 'Golang高并发'}]>

3.查询jason的作者的电话号码和地址
res = models.Author.objects.filter(name='barry').values('author_detail__phone', 'author_detail__addr')
print(res)
# <QuerySet [{'author_detail__phone': 110, 'author_detail__addr': '上海'}]>

'基于双下划线的反向跨表查询'
4.查询南方出版社出版的书籍名称和价格
res = models.Publish.objects.filter(name='南方出版社').values('book__title', 'book__price')
print(res)
# <QuerySet [{'book__title': 'Golang高并发', 'book__price': Decimal('19800.98')}, {'book__title': 'python数据分析', 'book__price': Decimal('29800.98')}]>

 5.查询jason写过的书的名称和日期
res = models.Author.objects.filter(name='barry').values('book__title', 'book__publish_time')
print(res)
# <QuerySet [{'book__title': 'django基础', 'book__publish_time': datetime.datetime(2022, 9, 5, 14, 18, 52, 900173, tzinfo=<UTC>)}, {'book__title': 'Golang高并发', 'book__publish_time': datetime.datetime(2022, 9, 5, 14, 19, 50, 130331, tzinfo=<UTC>)}]>

6.查询电话是110的作者姓名和年龄
res = models.AuthorDetail.objects.filter(phone=110).values('author__name', 'author__age')
print(res)
# <QuerySet [{'author__name': 'barry', 'author__age': '18'}]>

标签:objects,User1,models,res,查询,ORM,print,操作
From: https://www.cnblogs.com/riuqi/p/16660020.html

相关文章

  • 如何查询Oracle指定表名所在的表空间是什么?
    场景1:假设你知道完整的表名是student,那么可以使用下面的精确语句查询SELECT*FROMall_tablesWHEREUPPER(table_name)='STUDENT';场景2:假如你只知道表名的一部分,那么......
  • Mybatis学习笔记(七)——Mybatis关联查询
    级联关系是一个数据库实体的概念,有3种级联关系,分别是一对一级联、一对多级联以及多对多级联。例如,一个角色可以分配给多个用户,也可以只分配给一个用户。大部分场景下,我们......
  • 今日内容 表查询关键字 下划线查询以及跨表查询
    表查询数据准备及测试环境搭建1.django自带一个sqlite3小型数据库该数据库功能非常有限,并且针对日期类型的数据兼容性很差2.django切换mysql数据库django......
  • 操作系统(学习笔记)
    操作系统(学习笔记)  进程=正在进行的程序=执行中的程序进程程序的本质:数据和对数据的处理;进程的本质:正在运行(执行/动态)的程序;进程是操作系统进行资源化分配......
  • 数据库基础操作 part1
    初识数据库数据库相关概念数据库管理软件:本质就是一个C/S架构的套接字程序服务端套接字客户端套接字操作系统:Linux操作系统:随......
  • 表查询数据准备及测试环境搭建、ORM多表查询
    目录上周内容回顾视图层模块层今日内容详细一、表查询数据准备及测试环境搭建1.django自带一个sqlite3小型数据库2.django切换MySQL数据3.定义模型类4.数据库的迁移命令(模......
  • 47 | JAVA_数据库JDBC查询
    JDBC查询导入依赖因为我们选择了MySQL5.x作为数据库,所以我们首先得找一个MySQL的JDBC驱动。所谓JDBC驱动,其实就是一个第三方jar包,我们直接添加一个Maven依赖就可以了:<d......
  • 50 | JAVA_数据库JDBC_批量操作Batch
    JDBCBatch使用JDBC操作数据库的时候,经常会执行一些批量操作。例如,一次性给会员增加可用优惠券若干,我们可以执行以下SQL代码:INSERTINTOcoupons(user_id,type,expir......
  • 虚拟机下卸载操作系统之CentOS7
    虚拟机下卸载操作系统之CentOS7https://www.jianshu.com/p/5f35d4a47854......
  • R语言中rnorm、runif生成符合正太分布和均匀分布的随机数
     001、rnorm用于生成符合正态分布的随机数a<-rnorm(10)##生成10个均值为为0,标准差为1的符合正太分布随机数amean(a)sd(a)  a<-rnorm(10,3,5)......