2010-10-06 42 views
50

我想在另一個模型對象實例中。我提出這個錯誤:經理無法通過模型實例訪問

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 

回答

77

有問題的錯誤是在您嘗試訪問時引起的通過模型的一個實例。您已使用小寫字母類名稱。這很難說如果錯誤是由訪問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是非常具體的,我能夠提供一個解決方案。錯誤可能並不總是如此明顯。

+0

但是,'topic'似乎是實際的模型類,而不是根據他提供的代碼的實例。 – 2010-10-06 16:16:19

+0

@Daniel:真的。但是,只有當您嘗試使用實例訪問'Manager'時,纔會出現錯誤'Manager無法通過Foo實例訪問'。看到源代碼:http://code.djangoproject.com/svn/django/trunk/django/db/models/manager.py – 2010-10-06 16:18:18

+4

事實上,也許另一個原因(除了「這是最好的做法」)不使用小寫字母對於類名:)這將顯示他可能使用'topic'作爲本地實例變量並吹走對類的引用。 – 2010-10-06 16:19:44

31

Django的< 1.10

topic._default_manager.get(id=topic_id) 

雖然你不應該這樣使用它。該_default_manager和_base_manager是私有的,所以它的recomended使用它們只如果你的主題模型,裏面當你要使用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', ...] 
+4

謝謝,這個答案正是我一直在尋找的。我希望我能不止一次地投票。我的用例是當你爲抽象模型添加功能時,你不知道(在這個層次上)什麼是最終模型類。 – fadedbee 2012-05-20 06:11:51

+2

或者使用'topic .__ class __。objects.get(id = topic_id)'。 – Bentley4 2013-10-07 12:40:20

+0

這是一個古老的答案,但從Django v1.10開始,我不再看到這些私有方法。但是,「self .__ class __。objects」會根據您的其他答案進行處理。 – James 2017-02-08 20:23:16

28
topic.__class__.objects.get(id=topic_id) 
+0

從Django v1.10開始工作。 – James 2017-02-08 20:24:55

0

如果話題是一個ContentType實例(事實並非如此),這可能會起作用:

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

['model_class()'](https://docs.djangoproject.com/en/dev/ref/contrib/contenttypes/#django.contrib.contenttypes.models.ContentType.model_class)是ContentType的一種方法模型。其他模型實例,包括'topic',沒有'model_class'方法。 – Alasdair 2013-06-09 19:36:08

+0

對不起,我一定誤解了這個問題。我試圖解決一個看似相似的問題...... – Nimo 2013-06-16 15:39:58

3

也可能由一對偏見太多引起,例如

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

而不是正確的

ModelClass.objects.filter(...) 

發生在我有時當bpython(或者IDE)自動添加括號。

結果當然是一樣的 - 你有一個實例而不是一個類。