2015-04-02 58 views
0

我有兩個在與ManyToManyField關係Django模型Django的ManyToManyField訪問相關數據

Book模型

class Book(models.Model): 
    title = models.TextField() 
    authors = models.ManyToManyField('authors.Author') 

作者型號

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

比方說,我的最佳方式通過運行查詢

01獲取所有書籍
books = Book.objects.filter(name="some value").prefect_related('authors') 

什麼是優化的方式來讓所有的作者與上述結果書有關。

什麼,我想現在是

authors = [] 
for book in books: 
    for author in book.authors.all(): 
     authors.append(author.id) 
authors = Author.objects.filter(id__in=authors).distinct() 

但是這個看上去很昂貴。什麼是獲得相關作者設置的最佳途徑。

回答

2

即使使用昂貴的方法,也不需要在最後再次查詢作者:在每個內部循環中,author已經是一個Author實例,因此您可以將其添加到列表中而不是ID。

但是你說得對,有一個更便宜的方法來做到這一點,那就是直接在查詢中使用關係。與往常一樣,如果你想作者,你應該開始作者和遍歷書籍:

authors = Author.objects.filter(book__in=Book.authors.all()) 

這將轉化爲一個子查詢單個查詢。因爲這是一個簡單的JOIN

authors = Author.objects.exclude(book=None) 

,它應該讓你在這種情況下,相同的結果:

這可能是更便宜。

+0

是不是book_set,而不是你使用它作爲一個字段 – 2015-04-02 13:36:33

+0

沒有的方式,查找你總是使用字段的小寫名稱,無論它是向前還是向後。 – 2015-04-02 13:39:53

1

如果你只需要作者,你可以簡單地在book__name查詢:

authors = Author.objects.filter(book__name="some value") 

您可以使用.prefetch_related('book')預取書。如果你真的需要的兩本書和作者的簡單列表,你可以跳過prefetch_related和做到這一點:

books = Book.objects.filter(name="some value") 
authors = Author.objects.filter(book__in=books)