2011-08-11 59 views
1

在我的模型有類BookCategory這樣定義:不同的值

class Category(models.Model): 
    name = models.CharField() 

class Book(models.Model): 
    title = models.CharField() 
    categories = models.ManyToManyField(Category) 

我要的是一組是在categories引用Category實例給定查詢集Book實例的字段。

我知道我可以通過書籍查詢集迭代和收集的類別爲每本書,但是這似乎沒有效率的我,因爲這可能在一個SQL查詢中指出:

SELECT DISTINCT name 
FROM myapp_book_categorys JOIN myapp_category ON myapp_book_categorys.category_id=myapp_category.id 
WHERE myapp_book_categorys.book_id IN 
    (SELECT id FROM myapp_book WHERE ...); 

是原始SQL的正確的路要走還是有更高水平的解決方案效率可比?

回答

5

編輯:好吧,我之前沒有ManyToManyField進行測試,所以我猜測。新代碼!

books = Book.objects.filter(title__contains="T") 
categories = Category.objects.filter(book__in=books).distinct() 
+0

是,相當多的是,除了這本書的ID必須從一個查詢集 – Sergio

+0

提取我想你的解決方案,它提供了我這個錯誤:'FieldError:無法解析關鍵字'book_set'到字段中。' – Sergio

+0

@Sergio您應該能夠使用查詢集來代替列表。另外,我並不確定[反向關係](https://docs.djangoproject.com/en/1.3/ref/models/relations/)會被命名,因此您可能需要四處尋找才能找到。 – eric

2

你需要通過「書」字段進行過濾:

book_ids = list(Book.objects.filter(...).values_list('id', flat=True) 
categories_queryset = Category.objects.filter(book__in=book_ids).distinct() 
+0

......正如@ matt-s響應一次編輯。 – rewritten

+0

嘿,你有很多比我更快。 – eric

+0

@ matt-s,無論如何我upvoted你的答案,這只是缺少正確的過濾器名稱... – rewritten