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

问题描述 投票:0回答:8

我试图在另一个模型对象实例中获取模型对象实例,并提出此错误:

无法通过主题实例访问管理器

这是我的模型:

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
python django django-models instance django-managers
8个回答
171
投票

当您尝试通过模型实例访问模型的

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
,不适用于实例。有关详细信息,请参阅检索对象的文档。金钱报价:

Managers
只能通过模型类访问,而不是从模型实例访问,以强制“表级”操作和“记录级”操作之间的分离。 (强调)

更新

请参阅下面@Daniel 的评论。使用标题大小写作为类名是一个好主意(不,你必须:P)。例如 Topic 而不是

topic

。无论您是指实例还是类,您的类名都会引起一些混乱。由于

Manager isn't accessible via <model> instances
非常具体,我能够提供解决方案。错误可能并不总是那么明显。
    
topic.__class__.objects.get(id=topic_id)


77
投票
对于 Django 

33
投票

虽然你不应该这样使用它。 _default_manager 和 _base_manager 是私有的,因此建议仅当您位于主题模型内时才使用它们,就像当您想在专有函数中使用 Manager 时,比方说:< 1.10

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', ...]

也可能是由于一对括号太多造成的,例如

13
投票

而不是正确的

ModelClass.objects.filter(...)

当 bpython(或 IDE)自动添加括号时,有时会发生在我身上。

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

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


0
投票

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

0
投票

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

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

我在下面遇到了同样的错误:

0
投票
AttributeError:无法通过 CustomUser 实例访问管理器

当我使用

Manager

访问
request.user.objects

时,如下所示:

"views.py"

from django.http import HttpResponse

def test(request):
    print(request.user.objects)
    return HttpResponse("Test")
    

这是一个老话题,但如果有人遇到这个问题,请考虑检查你的视图方法,你可以在模型类实例中使用模型方法,在 Django 中,你应该直接在模型本身上使用模型方法,而不是在类实例上,所以举个例子:

0
投票

model = Model.objects.get(unique_id) model.objects.do_something()

你应该这样做

model = get_object_or_404(ModelClass, unique_id)
model.objects.do_something()

© www.soinside.com 2019 - 2024. All rights reserved.