关键词

详解Django的 select_related() 函数:对关联对象进行选择

Django select_related()函数

select_related()函数是Django中用于 优化查询性能 的一个重要函数。

使用select_related()可以使查询数据时,Django在所有涉及到联合查询的外键开始处进行一次性的联合查询,从而减少了多次访问数据库的必要性。

当一个查询涉及多个表时,使用select_related()可以有效地减少数据库的访问次数,提高性能。

select_related()函数用法

使用方法非常简单,只需要在查询的QuerySet中使用select_related()即可。

select_related()接收一个关键字参数,参数的值为需要连表查询的属性名,可以使用属性链来访问多个外键,例如:

Book.objects.select_related('author__publisher')

上面的代码使用select_related()查询Book表时,会从开始的Book表开始,查询关联的Author表的所有外键,接着查询Author表关联的Publisher表的所有外键。

查询完毕后,返回包含所有结果集的QuerySet,减少了访问关联表的次数和查询时间,提高了性能。

select_related()函数的实例

接下来,将使用两个实例来说明select_related()函数的作用和使用方法。

实例一

首先,假设有两个数据表,一个为Book表,另外一个为Author表,它们共同形成了外键,Book表中的字段如下:

class Book(models.Model):
    title = models.CharField(max_length=50)
    author = models.ForeignKey('Author', on_delete=models.CASCADE, related_name='books')

Author模型如下:

class Author(models.Model):
    name = models.CharField(max_length=30)
    age = models.IntegerField()
    email = models.EmailField()

如果我们需要查询Book表中的所有书籍,并且需要同时查询对应的作者信息,这时,我们可以使用以下代码:

books = Book.objects.all()

for book in books:
    author = book.author
    print('书名:%s 作者:%s'%(book.title, author.name))

以上代码中,每次打印出书籍名和作者姓名时,都需要查询一次Author数据表,查询的次数与Book数据表中的数据记录条数相等。而这样的查询方式导致数据库访问次数较多,查询效率降低。

为了减少查询次数,提高查询效率,可以使用select_related()函数。如下:

books = Book.objects.select_related('author')

for book in books:
    author = book.author
    print('书名:%s 作者:%s'%(book.title, author.name))

以上代码中,我们添加了select_related('author'),表示在查询时不仅查询Book表,还查询Author表。这样,每次查询时,都可以同时查询出对应的作者信息,减少了数据库访问次数。

实例二

除了普通的外键外,select_related()函数还可以使用属性链来查询多个外键。

以以下数据模型为例:

class Book(models.Model):
    title = models.CharField(max_length=50)
    author = models.ForeignKey('Author', on_delete=models.CASCADE, related_name='books')

class Author(models.Model):
    name = models.CharField(max_length=30)
    age = models.IntegerField()
    email = models.EmailField()
    publisher = models.ForeignKey(Publisher, on_delete=models.CASCADE, related_name='authors')

class Publisher(models.Model):
    name = models.CharField(max_length=30)
    address = models.CharField(max_length=50)

如果我们需要查询所有图书的详细信息,同时需要查询书籍对应作者的发布商信息,那么可以使用以下代码:

books = Book.objects.select_related('author__publisher')

for book in books:
    author = book.author
    publisher = author.publisher
    print('书名:%s 作者:%s 发布商:%s'%(book.title, author.name, publisher.name))

以上代码使用了select_related('author__publisher'),使得在查询Book表时,同时查询Author表和Publisher表,查询速度更快,效率更高。

总结

使用select_related()函数可以极大地优化查询性能,减少查询次数和时间。

在查询包含多个表的QuerySet时,在需要查询的外键属性前加上__(下划线)即可。

本文链接:http://task.lmcjl.com/news/16199.html

展开阅读全文