无法通过模型实例访问管理器

时间:2010-10-06 15:30:58

标签: django django-models instances django-managers

我正在尝试在另一个中获取模型对象实例。我提出这个错误:

 Manager isn't accessible via topic instance

这是我的模特:

class forum(models.Model):
    # Some attributs

class topic(models.Model):
    # Some attributs

class post(models.Model):
    # Some attributs

    def delete(self):
        forum = self.topic.forum
        super(post, self).delete()
        forum.topic_count = topic.objects.filter(forum = forum).count()

以下是我的观点:

def test(request, post_id):
    post = topic.objects.get(id = int(topic_id))
    post.delete()

我得到了:

post.delete()
forum.topic_count = topic.objects.filter(forum = forum).count()
Manager isn't accessible via topic instances

6 个答案:

答案 0 :(得分:98)

当您尝试通过模型实例访问模型的Manager时,会导致错误。您使用了小写类名。这使得很难说错误是否是由访问Manager的实例引起的。由于其他可能导致此错误的方案未知,我假设您以某种方式混淆了topic变量,以便您最终指向topic模型的实例而不是类。

这条线是罪魁祸首:

forum.topic_count = topic.objects.filter(forum = forum).count()
#                   ^^^^^

你必须使用:

forum.topic_count = Topic.objects.filter(forum = forum).count()
#                   ^^^^^
#                   Model, not instance.

出了什么问题? objects是类级别的Manager,而不是实例。有关详细信息,请参阅documentation for retrieving objects。钱报价:

  

Managers只能通过模型​​类(而非模型实例)访问 ,以强制执行“表级”操作与“记录 - 之间的分离 - 等级“操作。

(强调补充)

<强>更新

请参阅下面@Daniel的评论。对于类名使用标题案例是一个好主意(不,你必须:P)。例如Topic而不是topic。无论您是指实例还是类,您的类名都会引起一些混淆。由于Manager isn't accessible via <model> instances非常具体,我能够提供解决方案。错误可能不会那么明显。

答案 1 :(得分:41)

topic.__class__.objects.get(id=topic_id)

答案 2 :(得分:31)

对于django&lt; 1.10

topic._default_manager.get(id=topic_id)

虽然你不应该这样使用它。 _default_manager和_base_manager是私有的,所以只有当你在Topic模型中时才建议使用它们,就像你想在专有函数中使用Manager一样,让我们​​说:

class Topic(Model):
.
.
.
    def related(self)
        "Returns the topics with similar starting names"
        return self._default_manager.filter(name__startswith=self.name)

topic.related() #topic 'Milan wins' is related to:
# ['Milan wins','Milan wins championship', 'Milan wins by one goal', ...]

答案 3 :(得分:3)

也可能由一对过多的parantheses引起,例如

ModelClass().objects.filter(...)

而不是正确的

ModelClass.objects.filter(...)

有时当bpython(或IDE)自动添加parantheses时会发生。

结果当然是相同的 - 你有一个实例而不是一个类。

答案 4 :(得分:0)

如果主题是一个ContentType实例(它不是),那么这将起作用:

topic.model_class().objects.filter(forum = forum)

答案 5 :(得分:0)

我只是遇到了与此错误类似的问题。回顾一下您的代码,似乎也可能是您的问题。我认为您的问题是未将“ id”与“ int(topic_id)”和topic_id进行比较。

def test(request, post_id):
    post = topic.objects.get(id = int(topic_id))
    post.delete()

我猜你的代码应该使用“ post_id”而不是“ topic_id”

def test(request, post_id):
    post = topic.objects.get(id = int(post_id))
    post.delete()