当前位置:首页 > Web开发 > 正文

django之ORM的查询优化,Ajax

2024-03-31 Web开发

ORM查询优化 only与defer res = models.Book.objects.all().values('title') print(res) # <QuerySet [{'title': '三国演义'}, {'title': '红楼梦'}, {'title': '水浒传'}, {'title': '天龙八部'}]> for i in res: print(i,type(i)) # <class 'dict'> print(i.title) # AttributeError: 'dict' object has no attribute 'title' ,for循环出来就是第一个普通的字典,字典没有点取值的方式

only:查询only后括号内指定的字段,查询一次,之后再点字段不会再查数据库了;如果点的是其他字段,会再次操作数据库;

# 点指定字段 res = models.Book.objects.only('title') print(res) # 返回的是一个QuerySet对象,列表内是一个个类的对象; for i in res: print(i.title)

技术图片

# 点其他字段 res = models.Book.objects.only('title') # print(res) for i in res: print(i.price)

技术图片

refer:refer和only互为反关系,按照refer指定字段查找,操作数据库一次,之后对象点指定的属
性,每点一次,操作一次数据库;如果点其他字段,整体只操作一次数据库。

# 点指定字段 res = models.Book.objects.defer('title') # print(res) for i in res: print(i.title)

技术图片

# 点其他字段 res = models.Book.objects.defer('title') # print(res) for i in res: print(i.price)

技术图片

select_related与prefetch_related查询优化

select_related:括号内只能放外键字段,并且外键字段的类型只能是一对多,或者 一对一,不能是多对多;
内部是自动连表操作,会将括号内外键字段所关联的表与当前表自动拼接成一张表,然后将表中的数据一个个查询出
来封装成一个个的对象。这样做的好处就在于跨表也不需要重复的走数据库了,减轻数据库的压力。
select_related括号内可以放多个外键字段,逗号隔开,会将多个外键字段关联的表与当前表全部拼成一张大表。

res = models.Book.objects.select_related('publish') print(res) # <QuerySet [<Book: Book object>, <Book: Book object>, <Book: Book object>, <Book: Book object>]> for i in res: print(i.publish) # 只操作一次数据库 ''' Publish object Publish object Publish object Publish object '''

技术图片

一对多的情况:

res = models.Book.objects.select_related('publish') # print(res) for i in res: print(i.publish) # 只操作一次数据库

技术图片

一对一的情况:

res = models.Author.objects.select_related('author_detail') # print(res) for i in res: print(i.author_detail) # 内部做的也是联表操作,同一对多一样,,也是内连接

多对多的情况:

res = models.Book.objects.select_related('author') # print(res) for i in res: print(i.author) ''' 报错信息: django.core.exceptions.FieldError: Invalid field name(s) given in select_related: 'author'. Choices are: publish '''

prefetch_related:内部是子查询,会自动帮你按步骤查询多张表 然后将查询的结果封装到对象中,
给用户的感觉好像还是连表操作,括号内支持传多个外键字段 并且没有类型限制。
特点:每放一个外键字段 就会多走一条sql语句 多查询一张表

res = models.Book.objects.prefetch_related('publish','authors') # print(res) for i in res: print(i.publish,i.authors.all()) ''' Publish object <QuerySet [<Author: Author object>, <Author: Author object>]> Publish object <QuerySet []> Publish object <QuerySet []> Publish object <QuerySet []> '''

两者之间的优缺点比较

结合实际情况,看表的数据量的大小, 两张表都特别大的情况下,连表操作可能耗时更多; choices参数

choices字段类型,在获取值得时候统一的句式:get_字段名_display()

1.建表

# models.py文件 from django.db import models # Create your models here. class User(models.Model): username = models.CharField(max_length=32) password = models.BigIntegerField() gender_choices = ( (1,'男'), # 第一个参数可以是数字,也可以是自定义的字符串 (2,'女'), (3,'其他'), ) gender = models.IntegerField(choices = gender_choices)

2.数据库迁移命令 数据录入

这里我们使用的是django自带的测试用的db.sqlite3数据库,并在表中添加数据

菜单栏Tools>Run manage.py Task
django 终端:1.makemigrations 2.migrate

技术图片

温馨提示: 本文由Jm博客推荐,转载请保留链接: https://www.jmwww.net/file/web/41998.html