我指定了两个用于跟踪用户对文章实例进行投票的模型(在另一个应用中,在这种情况下为articlescraper
)。
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 shell中,我试图通过与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>]
这是预期的行为,并在UserProfile
和UpvotedArticle
类别的Django管理员中进行镜像。
但是,我不明白为什么尝试获取文章列表无法按照我最初尝试使用a.articles_upvoted.all()
的方式进行,如果这两个模型是链接的。
答案 0 :(得分:2)
因为这些关系并不相同。通过在一侧定义ForeignKey,在另一侧定义ManyToMany,您已经为数据库提供了两个单独的位置来存储有关文章upvoting的信息。
您应该删除ManyToManyField
上的UserProfile
,并使用自动反向关系:
a = UserProfile.objects.get(pk=1)
a.upvotedarticle_set.all()
或者,您可以将UpvotedArticle
识别为ManyToMany关系的“贯穿”表,并在articles_upvoted
的定义中明确标记它 - 请注意,该关系应该与{{ 1}},而不是articlescraper.Article
:
UpvotedArticle
虽然由于你没有在该关系上添加任何额外数据,这是定义显式直通表的常用原因,但您可能希望完全删除它并且只依赖于Django将创建的自动数据。