2012-07-31 175 views
0

我有两个模型指定用于跟踪哪些用户已upvoted文章实例(在另一个应用程序,在这种情况下,articlescraper)。ManyRelatedManager调用返回空列表时,它应该返回至少一个结果

from django.contrib.auth.models import User 

class UserProfile(models.Model): 
    user = models.OneToOneField(User) 

    articles_upvoted = models.ManyToManyField('useraccounts.UpvotedArticle', 
               null=True, 
               blank=True) 

class UpvotedArticle(models.Model): 
    article = models.ForeignKey('articlescraper.Article') 
    user = models.ForeignKey(User) 

在Django的壳,我试着用UserProfile互动的方式获取的文章列表:

a = UserProfile.objects.get(pk=1) 
a.articles_upvoted.all() 

将返回:

[] 

然而,那我走了稍微进一步:

b = UpvotedArticle.objects.filter(user=User.objects.get(pk=1)) 
b 

将返回:

[<UpvotedArticle: Arch Linux Lexmark S305 Drivers>, <UpvotedArticle: Structure of a Haystack project>] 

这是预期的行为,并反映在Django管理两个UserProfileUpvotedArticle类别。

但是,我不明白,为什么试图获取文章列表不能按照我最初尝试使用a.articles_upvoted.all()的方式完成,如果两个模型链接。

回答

2

因为这些关系并不相同。通过在一侧定义一个ForeignKey,在另一侧定义一个ManyToMany,您已经为数据库提供了两个单独的位置来存储有关文章upvoting的信息。

您应该删除ManyToManyFieldUserProfile,并且只使用自动反向关系:

a = UserProfile.objects.get(pk=1) 
a.upvotedarticle_set.all() 

或者,你可以承认UpvotedArticle为“通过”的多对多关系的表,它明确地标记为这样的在articles_upvoted定义 - 不过,请注意的关系应该是与articlescraper.Article,不UpvotedArticle

article_upvoted = models.ManyToManyField(articlescraper.Article, null=True, 
             blank=True, through=UpvotedArticle) 

虽然您并未在该关系中添加任何额外数据,这是通过定义显式通过表的常见原因,但您可能希望完全删除它并仅依靠Django将创建的自动数据。

相关问题