详解Django的 get_queryset() 函数:获取查询集合

  • Post category:Python

get_queryset()是Django中一个经常使用的方法,用于指定一个视图中所需要的数据库查询集。它允许您返回包含特定条件下的查询结果的QuerySet,从而节省了在每个视图中重复查询数据库的时间和代码。在本次回答中,我将为您提供关于get_queryset()函数的详细说明和它的使用方法。

get_queryset() 函数

get_queryset()函数是Django中一个用于定义视图所使用查询集的方法。它允许开发者根据特定条件过滤一段数据。这个方法通常用于在视图中返回结果集。例如,如果您编写了一个blog视图,并且希望显示所有标题是“Django”的文章,则可以使用get_queryset()过滤出来。

使用方法

在创建视图类的时候,通过重写get_queryset()函数实现自己的查询。

例如,我们要创建一个显示所有文章的视图,但是并不是所有文章都公开发布,我们需要只显示已发布的文章,那么我们可以这么写:

from django.views.generic import ListView
from myapp.models import Article

class ArticleListView(ListView):
    model = Article

    def get_queryset(self):
        return Article.objects.filter(published=True)

这里重写了get_queryset()方法来过滤已发布的文章,这个方法会返回一个新的QuerySet,只包含已发布的文章。

还可以使用 super() 方法来调用父类的 get_queryset() 方法,然后再进行进一步的自定义查询,例如:

class ArticleListView(ListView):
    model = Article

    def get_queryset(self):
        qs = super(ArticleListView, self).get_queryset()
        return qs.filter(published=True)[:5]

这个例子中,在父类方法的基础上,我们只选择前5篇已发布的文章。

示例

下面提供两个用例说明,以便更好地理解这个方法:

用例1:假设有一个Book模型,其中包含了title(书名)、author(作者)、pub_date(出版日期)、price(价格)、publisher(出版社)几个字段。现在我们要在一个页面上展示价格小于100元的书籍,最近出版的5本书。

代码示例:

from django.views.generic.list import ListView
from myapp.models import Book

class BookListView(ListView):
    model = Book

    def get_queryset(self):
        qs = super(BookListView, self).get_queryset()
        return qs.filter(price__lt=100).order_by('-pub_date')[:5]

这里我们重写了get_queryset()函数以过滤,我们只选择价格小于100元的书,然后根据出版日期逆序排序,最后只选择前5本。

用例2:跨表查询,假设有一个Author模型,其中包含了name(姓名)和books字段,books字段是一个ManyToManyField类型,它关联到Book模型,表示该作者所写的所有书。现在我们要在展示一个作者页面时显示该作者的所有书籍。

代码示例:

from django.views.generic.detail import DetailView
from myapp.models import Author

class AuthorDetailView(DetailView):
    model = Author

    def get_queryset(self):
        qs = super(AuthorDetailView, self).get_queryset()
        return qs.prefetch_related('books')

在这个例子中,我们重写了get_queryset()方法来获取所有的相关书籍。我们使用prefetch_related()方法来优化查询,这样在渲染模板的时候,我们可以在模板中直接访问关联的书籍,并且不需要再进行额外的查询。