一起学习Django框架(六)模型层:ORM单表查询;ORM多表查询


简介:

本章节将基于模型层操作数据库里面的表了,不再是之前的单表操作;此次引入了表的设计、基于外键字段增删改查、基于对象跨表查询、基于双下划线跨表查询。


单表查询实验环境准备

我们需要新建一个Django项目,为了便于我们更加方便操作模型层,有两种方式可以直接调用到模型层。

方式一:在Django自带的测试环境

在这里插入图片描述
方式二:在项目内的任意py文件内,推荐在应用下面的一个tests.py文件进行

import os

if __name__ == "__main__":
	# 注意:mysite.settings修改成自己的!!项目名.settings
    os.environ.setdefault("DJANGO_SETTINGS_MODULE", "mysite.settings")
    import django
    django.setup() # 以独立的方式运行Django程序
    
    # 以下编辑我们需要的代码:

我们实验就使用Sqlite数据库了,首先要启动一下Django项目,然后这个数据库就被创建起来了,再使用pycharm进行连接:

选择Sqlite数据库路径(默认在项目根路径下)注意:一定要选中当前Django项目路径,如果选中错误,后面就会看不到我们创建的表了。
在这里插入图片描述
试验前夕环境准备完毕,接下来该准备数据库表了。


一、单表查询

1.1 创建实验表

在开始前,我们先在models.py文件里面创建如下实验表:

# 每个表的ID字段默认创建,会自动设置成主键且自增

# 每个表的ID字段默认创建,会自动设置成主键且自增

class Test(models.Model):  # 表名
    author = models.CharField(max_length=30)  # 作者名称
    title = models.CharField(max_length=30)  # 书籍名称
    price = models.FloatField()  # 书籍价格
    publish = models.CharField(max_length=30)  # 出版社名称

在项目根目录下再进行数据库迁移命令:

python3 manage.py makemigrations
python3 manage.py migrate

此时刷新一下sqllite就可以看到我们创建的表
在这里插入图片描述
我们现在可以对这个表进行操作了!


1.2 实例

tests.py,保持这种格式

import os

if __name__ == "__main__":
    os.environ.setdefault("DJANGO_SETTINGS_MODULE", "Day06.settings")
    import django
    django.setup()
    # 需要编写的代码放在这行注释下面:
    

先对表增加几条数据,我们就可以执行这个tests.py文件。

from app01.models import Test
Test.objects.create(author='张三',title='斗破苍穹',price=80.5,publish='武汉出版社')
Test.objects.create(author='李四',title='西游记',price=85.5,publish='北京出版社')
Test.objects.create(author='王五',title='水浒传',price=79.0,publish='北京出版社')

此时我们再来查询看看效果,我们对但条记录有两种方式查询:

  • filter括号内可以放多个参数 默认是and关系 推荐使用 条件不符合不会报错
  • get括号内可以放多个参数 默认是and关系 不推荐使用 条件不符合直接报错

filter拿到的是一个QuerySet对象,而get直接拿到的就是结果。但是程序是尽可能避免出错情况的,所以我们这里以filter作为查询方式

# QuerySet对象类似于列表,该列表内包含了filter查询到的结果。
obj = Test.objects.filter(title='斗破苍穹').first()
print(obj.author,obj.publish) # 拿到的是一个对象,该对象包含了这一条记录的所有值。

执行结果:

张三 武汉出版社

演示:当使用fileter与get查询不存在的记录时

print(Test.objects.filter(title='error'))
print(Test.objects.get(title='error'))

效果所示:get也就比filter快一步拿到结果,但是遇到没找到记录时它会报错,而filter不会
在这里插入图片描述
使用filter查询到的结果都会放到一个QuerySet对象里面去,而里面存储的就是对象的形式查询结果,可以通过QuerySet里面取出的对象.字段名拿到数据。


1.3 查看ORM使用的SQL语句

当返回的结果还是QuerySet对象的时候,我们可以通过query查看一下SQL语句是如何执行的

 obj = Test.objects.filter(title='斗破苍穹')
 print(obj)
 print(obj.query)

打印结果
在这里插入图片描述
方式二:实现我们使用ORM执行查询操作时在终端显示SQL语句

通过在settings.py结尾添加如下内容:

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查询操作那么就会在终端打印SQL语句

obj = models.Test.objects.filter(title='斗破苍穹')
print(obj)

执行效果如下:
在这里插入图片描述


补充:

当我们需要查询某个表的主键值=1的数据,那么我们就需要知道主键对应的字段名是什么,通常是id;但是为了避免有些表的主键字段名不是id的情况,此时我们可以通过填写字段时加上pk参数就可以直接对应到主键字段了;

obj = Test.objects.fileter(pk=1); # 获取Test表主键字段值为1的数据

1.3 单表查询常用方法

上面只是粗略介绍了一下,常规如何进行单表查询操作,这里介绍一些常用的查询API,可以更简便的帮助我们日后来操作表。

1、all() 查询所有元素

2、filter() 它包含了与所给筛选条件相匹配的对象

3、get() 返回与所给筛选条件相匹配的对象,返回结果有且只有一个,如果符合筛选条件的对象超过一个或者没有都会抛出错误。

4、first() 获取第一个元素

obj = Test.objects.all().first() # QuerySet对象里面第一个元素
print(obj)
print(obj.title)

# Test.objects.all()[0] 这种方式也是可以取到第一个元素的
# 但是如果没有元素可取则会报错,而使用first()则返回None

执行结果:

Test object (1)
斗破苍穹

5、last() 获取最后一个元素

obj = Test.objects.last()
print(obj)
print(obj.title)

执行结果

Test object (3)
水浒传

当我们需要对整个表的记录进行查询时,可以忽略all()。如:Test.objects.first() == Test.objects.all().first()

6、values() 获取指定字段的值

obj = Test.objects.values('title','publish')
print(obj)

执行结果

<QuerySet [{
   'title': '斗破苍穹', 'publish': '武汉出版社'}, {
   'title': '西游记', 'publish': '北京出版社'}, {
   'title': '水浒传', 'publish': '北京出版社'}]>

此时我们也可以通过first()、last()、[]等取值。

7、value_list() 获取指定字段的值

它与values()的区别是:value_list()返回的是列表套元组,也就是说没有对应字段名了,只有字段值

obj = Test.objects.values_list('title','publish')
print(obj)

执行结果

<QuerySet [('斗破苍穹', '武汉出版社'), ('西游记', '北京出版社'), ('水浒传', '北京出版社')]>

8、order_by() 排序

根据某个字段进行排序


                
  • 2
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值