在 Django 中,双下划线 (__) 通常用于查询的字段查找器(field lookups)和跨表查询(join)操作, 它允许你通过一条查询语句idu查询关联表中的字段。
示例模型 Autor 和 Book
from django.db import models
class Author(models.Model):
name = models.CharField(max_length=100)
class Book(models.Model):
title = models.CharField(max_length=100)
author = models.ForeignKey(Author, on_delete=models.CASCADE)
跨表查询
要查询 Book
表中与某个 Author
相关联的记录,可以使用双下划线连接相关字段。
查询某个作者的所有书籍
例如,查询某个特定作者(Author
)的所有书籍(Book
):
# 获取名为 "John Doe" 的作者
author = Author.objects.get(name="John Doe") # 查询 "John Doe" 所有的书籍 books_by_john_doe = Book.objects.filter(author=author)
也可以直接使用跨表查询来完成相同的任务:
# 查询 "John Doe" 所有的书籍(注意:author__name双下划线)
books_by_john_doe = Book.objects.filter(author__name="John Doe")
查询书名包含特定词的作者(模糊查询)
要查询书名包含某个特定词的所有作者,可以这样做:
# 查询书名包含 "Django" 的所有作者,用了两个双下划线
authors_with_django_books = Author.objects.filter(book__title__icontains="Django")
更多复杂查询
Django 的 ORM 还允许你进行更复杂的查询。例如:
查询特定作者书籍的数量
要查询每个作者的书籍数量,可以使用 annotate
和 Count
:
# 查询每个作者的书籍数量 authors_book_count = Author.objects.annotate(num_books=Count('book')).values('name', 'num_books')
多级联表查询
如果有更多的关联表,可以继续使用双下划线。三级光联,例如:
class Publisher(models.Model):
name = models.CharField(max_length=100)
class Author(models.Model):
name = models.CharField(max_length=100)
publisher = models.ForeignKey(Publisher, on_delete=models.CASCADE)
class Book(models.Model):
title = models.CharField(max_length=100)
author = models.ForeignKey(Author, on_delete=models.CASCADE)
查询出版商名字为 "TechBooks" 的所有书籍:
books_from_techbooks = Book.objects.filter(author__publisher__name="TechBooks")
通过双下划线,Django ORM 提供了一种强大且灵活的方式来执行复杂的数据库查询,而无需编写生涩的 SQL 代码