【问题标题】: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

【问题讨论】:

    标签: django django-models instance django-managers


    【解决方案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() 似乎不起作用
        猜你喜欢
        • 2011-07-29
        • 1970-01-01
        • 2021-10-08
        • 1970-01-01
        • 1970-01-01
        • 2011-09-24
        • 2012-12-04
        • 2022-06-16
        • 1970-01-01
        相关资源
        最近更新 更多