2017-05-18 8 views
0

クラス内の関連オブジェクトをフィルタリングする方法はありますか?私は、関連するオブジェクトによるフィルタリングについて言及するのではなく、クラス内の関連するオブジェクト自体をフィルタリングすることについて言及しています。おそらく例では、より良い説明します:DjangoのORMで関連する "下流"オブジェクトをフィルタリングしますか?

は、私は次のモデルがあるとしましょう:

class Book(models.Model): 
    title = models.CharField(max_length=200) 
    author = models.ForeignKey('Author', null=True) 
    isbn = models.CharField('ISBN',max_length=13) 
    genre = models.ManyToManyField(Genre) 


class Genre(models.Model): 
    name = models.CharField(max_length=200) 
    ... 

class Author(models.Model): 
    first_name = models.CharField(max_length=100) 
    last_name = models.CharField(max_length=100) 
    date_of_birth = models.DateField(null=True, blank=True) 
    date_of_death = models.DateField('Died', null=True, blank=True) 

私は特定のジャンルのためのすべての書籍を取得するなどの簡単なフィルタリングを行う方法を知っている:

books = Books.objects.filter(genre=1) 

とビューでこれをループします。

{% for book in books %} 
    {{book.title}} 
{% endfor %} 

クエリーセットの関連オブジェクトをフィルタリングしますか?

{% for book in author.books_set.all %} 
    {{book.title}} 
{% endfor %} 

私が期待するように私は(彼の本のすべてを取得して:私はこれを行う場合は

:のは、私はすでにフィルター著者のクエリセットを持っていると私は特定のジャンルからの彼の本をリストしたいとしましょう欲しいです)。

{% for book in author.books_set.filter(genre=1) %} 
    {{book.title}} 
{% endfor %} 

は、私が唯一の関連するオブジェクトのフィルタリングされたリストを取得していますように:

しかし、このような何かを行う方法はありますか?

テンプレートでロジックを混在させたくないので、これをビューまたはクラスメソッドとして行うことをお勧めします。

すなわち:

{% for book in author.books.filtered_genres %} 
    {{book.title}} 
{% endfor %} 

しかし、私はこれを行うための最善かつ最も神託(またはdjangonic :))方法を見つけ出すように見えることはできません。

さまざまなクエリセットをループし、私が望むものを構築することで、自分自身でデータ構造を構築することができますが、すでに定義されているデータモデルと関係を維持しようとしていました。

私は何を達成しようとしていますか?それとも、私がやろうとしていることをもっと詳しく説明できますか?

ありがとうございます!

答えて

0

@Doru:

が、私はこれを動作させることができなかった、

auths = Author.objects.filter(author='Bob').prefetch_related(book__genre=1) 

TypeError: prefetch_related() got an unexpected keyword argument 'book__genre' 

ためにエラーが発生しました。しかし、あなたは正しい道に私を置きます!私はプリフェッチメソッドがドキュメントに見つかりました。
は、これは私が、必要に応じて、私がやったと働いて得たものである:

auths = Author.objects.filter(author='Bob').prefetch_related(Prefetch('book_set', queryset=Book.objects.filter(genre=3), to_attr='filtered_books'))   

はその後、ちょうどテンプレートで、次の使用:

ので
{% for book in author.filtered_books %} 
    {{book.title}} 
{% endfor %} 

、正しい道に私を入れてくれてありがとう!

2

あなたはBookモデルにクエリセットに複数のフィルタを適用するか、連結することができます:

books = Books.objects.filter(author='Bob', genre=1) 

または

books = Books.objects.filter(author='Bob').filter(genre=1) 

か - あなたは関連するオブジェクトをクエリセットしたい場合 - あなたはprefetch_relatedメソッドを使用することができます。

author_genre_books = Author.objects.filter(author='Bob').prefetch_related(book_set__genre=1) 
関連する問題