我正在尝试在另一个中获取模型对象实例。我提出这个错误:
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
答案 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()