2011-03-18 78 views
1

外鍵向後導航對於這個例子:在Django

class Blog(models.Model): 
    name = models.CharField(max_length=100) 
    tagline = models.TextField() 

    def __unicode__(self): 
     return self.name 

class Author(models.Model): 
    name = models.CharField(max_length=50) 
    email = models.EmailField() 

    def __unicode__(self): 
     return self.name 

class Entry(models.Model): 
    blog = models.ForeignKey(Blog, related_name='entries') 
    headline = models.CharField(max_length=255) 
    body_text = models.TextField() 
    pub_date = models.DateTimeField() 
    mod_date = models.DateTimeField() 
    authors = models.ManyToManyField(Author) 
    n_comments = models.IntegerField() 
    n_pingbacks = models.IntegerField() 
    rating = models.IntegerField() 

    def __unicode__(self): 
     return self.headline 

所以,如何找到它的所有條目博客?

我想要做這樣的事情

q = Blog.objects.all().entries.filter(...) 

但它給了我一個錯誤。那麼Django只支持只使用一個對象而不是一組對象的後退導航屬性?

回答

4

比方說,你要對所有博客條目篩選,並獲得有條目博客你需要:

Blog.objects.filter(entry__headline__icontains="cats").distinct() 

有一個博客,許多條目的關係在這裏,但是這個查詢起作用並且給你帶有頭條新聞的貓的博客。

0

如果你想獲得與每個Blog相關聯的所有條目,你可以這樣做:

blogs = Blog.objects.all() 
for blog in blogs: 
    blog.cached_entries = blog.entry_set.all() 

雖然這看起來整潔,n + 1查詢將進行 - 1個查詢得到所有博客加N查詢獲取與博客相關的每個條目。

只用一個查詢就可以做到這一點,但如果您想按博客分隔條目,則必須做更多的工作。

blog_with_entries = [] 
entries = Entry.objects.order_by('blog') 
previous_blog = None 
acc_entries = [] # accumulate entries of one blog 

for entry in entries: 
    if previous_blog != entry.blog: 
     if previous_blog is not None: 
      blog_with_entries.append((previous_blog, acc_entries)) 
     acc_entries = [] 
     previous_blog = entry.blog 
    acc_entries.append(entry) 
blog_with_entries.append((previous_blog, acc_entries))