web-dev-qa-db-ja.com

モデルインスタンスを介してマネージャーにアクセスできない

別のモデルオブジェクトインスタンスを取得しようとしています。そして、私はこのエラーを発生させます:

 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
64
ThomasDurin

問題のエラーは、モデルのインスタンスを介してモデルの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は、モデルインスタンスからではなく、モデルクラス経由でのみアクセス可能ですonly 「テーブルレベル」の操作と「レコードレベル」の操作を分離します。

(エンファシスを追加)

更新

以下の@Danielのコメントを参照してください。クラス名にタイトルケースを使用することをお勧めします(そう、MUST:P)。たとえば、Topicではなくtopicです。クラス名は、インスタンスとクラスのどちらを参照している場合でも混乱を引き起こします。 Manager isn't accessible via <model> instances私は解決策を提供できる非常に具体的です。エラーは常に自明ではないかもしれません。

100
Manoj Govindan
topic.__class__.objects.get(id=topic_id)
43
mihaicc

Django <1.10

topic._default_manager.get(id=topic_id)

このように使うべきではありませんが。 _default_managerと_base_managerはプライベートであるため、独自の関数でManagerを使用する場合など、Topicモデル内にいる場合にのみ使用することをお勧めします。

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

一対のパラセシスによっても引き起こされる可能性があります。

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

正しいのではなく

ModelClass.objects.filter(...)

Bpython(またはIDE)が自動的にparanthesesを追加するときに時々私に起こります。

もちろん、結果は同じです。クラスの代わりにインスタンスがあります。

4
Markus

トピックがContentTypeインスタンスである場合(そうではない)、これは機能します。

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

このエラーと同様の問題が発生しました。そして、あなたのコードを振り返ると、それもあなたの問題かもしれないようです。あなたの問題は、「id」と「int(topic_id)」およびtopic_idの比較が設定されていないことだと思います。

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

あなたのコードは「topic_id」ではなく「post_id」を使用する必要があると思います

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