0

我有 3 个模型:

class Author(models.Model):
    title = CharField()

class Genre(models.Model):
    title = CharField()

class Book(models.Model):
    title = CharField()
    author = ManyToManyField(Author)
    genre = ManyToManyField(Genre)

我有一个包含所有流派和作者的复选框表单(多选),其中复选框值是项目(流派或作者)ID。

目的:显示具有选定作者或流派的书籍(不重复)

我可以通过两种方式做到这一点:

第一种方式:

if request.POST:
    book_list = Book.objects.all() #get all books from db
    books = []  

    request_list = request.POST.getlist('genre') #select list of genres in request
        for item in request_list:
            add_book = report_list.filter(genre=r_request) #queryset of book filtered by each genre 
            books.append(add_book) 
            book_list = book_list.exclude(genre=item)

    request_list = request.POST.getlist('author') #select list of authors in request
        for item in request_list:
            add_book = report_list.filter(author=item) #queryset of book filtered by each author 
            books.append(add_book) 
            book_list = book_list.exclude(author=item)
    return ...
        'books': books

但是当我选择很多作者和流派时,这种方式很慢,因为排除很慢。

第二种方式:

删除book_list = book_list.exclude(...)并应用模板标签 {% ifchanged book.id %}

但是我认为,当我在请求结果中获得 1000 多本书时,这也会很慢(书)

如何快速显示选定作者和类型的书籍?

4

2 回答 2

3

您正在遍历一个列表,并且对于列表中的每个项目,您都要求进行 SQL 查询。

每个 SQL 查询都在整个表数据库上运行以获取结果(除非组织得当)。

因此,您可以使用__in查找从列表中过滤:

“具有列表中的作者和列表中的流派的书籍”

genre_list= request.POST.getlist('genre')
author_list = request.POST.getlist('author')
books = Book.objects.filter(genre__in=genre_list,author__in=author_list)

“具有该类型作者的书籍”

from django.db.models import Q
genre_list= request.POST.getlist('genre')
author_list = request.POST.getlist('author')
books = Book.objects.filter(Q(genre__in=genre_list) | Q(author__in=author_list))

您还可以阅读django queryset 中的两个或多个 __in 过滤器......他们使用 Q 对象将查询连接到一个过滤器中。

于 2011-05-19T07:38:40.993 回答
1

在我看来:

genre_list= request.POST.getlist('genre')
author_list = request.POST.getlist('author')

query = None

if gender_list:
    gender_q = Q(genre__in=genre_list)
    query = gender_q

if author_list:
    author_q = Q(author__in=author_list)
    if gender_list:
       query|=author_q
    else:
       query = author_q

books = []
if query:
   books = Book.objects.filter(query).distinct()

http://docs.djangoproject.com/en/1.3/topics/db/queries/#complex-lookups-with-q-objects

于 2011-05-19T12:24:03.923 回答