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

发布于 2024-09-26 04:57:15 字数 728 浏览 5 评论 0原文

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

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

这是我的模型:

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

I'm trying to get model objects instance in another one and I raise this error :

Manager isn't accessible via topic instance

Here's my model :

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()

Here's my view :

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

And I get :

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(8

空‖城人不在 2024-10-03 04:57:15

当您尝试通过模型实例访问模型的 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,而不是在实例级别。有关详细信息,请参阅检索对象的文档。金钱报价:

管理器只能通过模型​​类访问,而不是从模型实例访问,以强制“表级”操作和“记录级”操作。

(已添加强调)

更新

请参阅下面@Daniel 的评论。使用标题大小写作为类名是一个好主意(不,你必须:P)。例如主题而不是主题。无论您是指实例还是类,您的类名都会引起一些混乱。由于 Manager 无法通过访问实例非常具体,我能够提供解决方案。错误可能并不总是那么明显。

The error in question is caused when you try to access the Manager of a model through an instance of the model. You have used lower case class names. This makes it hard to say if the error is caused by an instance accessing the Manager or not. Since other scenarios that can cause this error are unknown I am proceeding on the assumption that you have somehow mixed up the topic variable so that you end up pointing to an instance of the topic model instead of the class.

This line is the culprit:

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

You have to use:

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

What is going wrong? objects is a Manager available at the class level, not to the instances. See the documentation for retrieving objects for details. Money quote:

Managers are accessible only via model classes, rather than from model instances, to enforce a separation between "table-level" operations and "record-level" operations.

(Emphasis added)

Update

See the comments from @Daniel below. It is a good idea (nay, you MUST :P) to use title case for class names. For instance Topic instead of topic. Your class names cause some confusion whether you are referring to an instance or a class. Since the Manager isn't accessible via <model> instances is very specific I am able to offer a solution.The error may not be so self evident always.

野却迷人 2024-10-03 04:57:15
topic.__class__.objects.get(id=topic_id)
topic.__class__.objects.get(id=topic_id)
东北女汉子 2024-10-03 04:57:15

对于 django < 1.10

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

For django < 1.10

topic._default_manager.get(id=topic_id)

Though you should not use it like this. The _default_manager and _base_manager are private, so it's recomended to use them only if you're inside the Topic model, like when you want to use the Manager in a proprietary function let's say:

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', ...]
请远离我 2024-10-03 04:57:15

也可能是由一对括号太多引起的,例如,

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

而不是正确的

ModelClass.objects.filter(...)

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

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

Could also be caused by a pair of parantheses too many, e.g.

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

instead of the correct

ModelClass.objects.filter(...)

Happens to me sometimes when bpython (or an IDE) automatically adds parantheses.

The result, of course, is the same - you have an instance instead of a class.

分开我的手 2024-10-03 04:57:15

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

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

if topic were a ContentType instance (which it is not), this would have worked:

topic.model_class().objects.filter(forum = forum)
情泪▽动烟 2024-10-03 04:57:15

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

I just had an issue similar to this error. And looking back at your code it seems that it could be your issue too. I think your issue is that your comparing "id" to "int(topic_id)" and topic_id is not set.

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

I'm guessing your code should use "post_id" not "topic_id"

def test(request, post_id):
    post = topic.objects.get(id = int(post_id))
    post.delete()
望喜 2024-10-03 04:57:15

我得到了同样的错误如下:

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

当我使用 request.user.objects 访问 Manager 时,如下所示:

"views.py"

from django.http import HttpResponse

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

I got the same error below:

AttributeError: Manager isn't accessible via CustomUser instances

When I accessed Manager with request.user.objects as shown below:

"views.py"

from django.http import HttpResponse

def test(request):
    print(request.user.objects)
    return HttpResponse("Test")
软糖 2024-10-03 04:57:15

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

这会引发错误

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

,你应该这样做

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

This is a old topic but if anyone encountering this issue, consider checking your view method, you may used model methods in a model class instance, in Django, you should use model methods directly on to model itself but not on the class instances, so with examples:

this will raise an error

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

and you should do

model = get_object_or_404(ModelClass, unique_id)
model.objects.do_something()
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文