我有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多本书时,这也会非常缓慢
如何快速展示选定作者和流派的书籍?
答案 0 :(得分: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))
您还可以阅读Two or more __in filters in django queryset ...他们使用Q对象将查询连接到一个过滤器中。
答案 1 :(得分: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