2009-12-01 277 views
22

我有这样定义的模型:“RelatedManager”对象没有属性

class UserDetail(models.Model): 
    user = models.ForeignKey(User, db_index=True, unique=True, related_name='details') 
    favourites = models.ManyToManyField(Article, related_name='favourited_by', blank=True) 

而且我试图做这样的事情:

article = get_object_or_404(Article, pk=id) 
request.user.details.favourites.add(article) 

为什么不工作?

我得到这个错误:

'RelatedManager' object has no attribute 'favourites'

我猜details是不正确的类型,但为什么不呢?我该如何执行这样的查询?

回答

36

当您访问user.details时,它将访问UserDetail.user外键的反向引用。外键本身并没有指定User只能有一个UserDetail,所以django为你提供了一个RelatedManager,你可以像正规的Manager一样过滤和查询。所以你对你做的事情和你对你的经理做的一样。您可以要求提供user.details.all()user.details.filter(),user.details.get()等,根据方法和结果,它们会为您提供查询集,对象或异常。

+1

哦!现在这变得更有意义了。我猜这很明显,*我*,用户只有一个'UserDetail',但我想这不是在任何地方指定的。谢谢。 – mpen 2009-12-01 04:22:05

+8

如果您更改了模型,而不是使用ForeignKey,则使用了OneToOneField,您可以完全按照您的预期进行操作。 OneToOneFields与ForeignKeys类似,只不过由于它们只是一个相关对象,所以Django将直接访问该对象,而不是通过相关管理器。 请参阅https://docs.djangoproject.com/en/dev/ref/models/fields/#onetoonefield – mbargiel 2013-01-28 17:40:28

8

尝试

request.user.details.get().favourites.add(article) 

这是假设UserDetail对象已存在该用户,否则get()将引发异常。