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

Posted

技术标签:

【中文标题】无法通过模型实例访问管理器【英文标题】:Manager isn't accessible via model instances 【发布时间】:2011-04-21 21:52:42 【问题描述】:

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

 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

【问题讨论】:

【参考方案1】:

我刚刚遇到了与此错误类似的问题。回顾您的代码,它似乎也可能是您的问题。我认为您的问题是您将“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()

【讨论】:

【参考方案2】:

对于 django

topic._default_manager.get(id=topic_id)

虽然你不应该这样使用它。 _default_manager 和 _base_manager 是私有的,因此建议您仅在主题模型中使用它们,例如当您想在专有功能中使用 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', ...]

【讨论】:

谢谢,这个答案正是我一直在寻找的。我希望我能多次投票。我的用例是当您向抽象模型添加功能时,您将不知道(在此级别)最终模型类的名称。 或使用topic.__class__.objects.get(id=topic_id) 这是一个旧答案,但从 Django v1.10 开始,我不再看到这些私有方法。但是,self.__class__.objects 可以根据您的其他答案解决问题。【参考方案3】:

也可能是一对花括号过多引起的,例如

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

而不是正确的

ModelClass.objects.filter(...)

有时当 bpython(或 IDE)自动添加括号时,我会遇到这种情况。

结果当然是一样的——你有一个实例而不是一个类。

【讨论】:

【参考方案4】:

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

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

【讨论】:

model_class()ContentType 模型的方法。其他模型实例,包括topic,没有model_class 方法。 对不起,我一定是看错了问题。我试图解决一个看似相似的问题......【参考方案5】:
topic.__class__.objects.get(id=topic_id)

【讨论】:

从 Django v1.10 开始工作。 这个__class__ 也适用于抽象模型中的方法,因为我们不知道后代类的实际名称。在这种情况下,我使用了self.__class__.objects.get models.py 模型上表现出色。 def get_object(self): return self.__class__.objects.get(...)。将其用于GenericForeignKey【参考方案6】:

当您尝试通过模型的实例访问模型的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 的 cmets。对类名使用标题大小写是个好主意(不,你必须:P)。例如 Topic 而不是 topic。无论您指的是实例还是类,您的类名都会引起一些混淆。由于Manager isn't accessible via <model> instances 非常具体,我能够提供解决方案。错误可能并不总是那么不言自明。

【讨论】:

然而,topic 似乎是实际的模型类,而不是根据他提供的代码的实例。 @Daniel:是的。然而,只有当您尝试使用实例访问 Manager 时,才会出现错误 Manager isn't accessible via Foo instances。见源码:code.djangoproject.com/svn/django/trunk/django/db/models/… 确实,也许是另一个原因(除了“这是最佳实践”)不使用小写字母作为类名 :) 看起来他可能会使用 topic 作为局部实例变量并吹走对类的引用。 你应该用过topic.model_class().objects 你也可以使用topic.__class__.objects。上面@Nimo 提到的model_class() 似乎不起作用

以上是关于无法通过模型实例访问管理器的主要内容,如果未能解决你的问题,请参考以下文章

gis模型构建器无法连接按属性选择

为啥需要下载管理器来利用通过 isp 从加利福尼亚的计算机访问弗吉尼亚的 ec2 实例提供的完整下载速度?

无法访问 Service Fabric 本地群集管理器

无法访问本地主机上的 API 资源管理器

模型管理器可以访问其模型的元属性(`Meta.unique_together`)吗?

IIS管理器无法验证此内置帐户是不是有访问权