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である、すべてのジャンルと作者を含むチェックボックスフォーム(複数選択)があります。

目的:選択した著者またはジャンルの本を表示する (重複なし)

私は2つの方法でこれを行うことができます:

最初の方法:

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

しかし、多くの著者やジャンルを選択すると、除外が非常に遅いため、この方法は非常に遅くなります。

2 番目の方法:

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 で Two or more __in フィルターを読み取ることもできます... Q オブジェクトを使用して、クエリを 1 つのフィルターに連結します。

于 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 に答える