Manager unavailable through model instances

I am trying to get an instance of model objects in another. And I cause this error:

Manager isn't accessible via topic instance 

Here is 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 is 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 
+61
django django-models instances django-managers
Oct 6 '10 at 15:30
source share
6 answers

An error occurs when you try to access the Model Manager through an instance of the model. You have used lowercase class names. This makes it difficult to state whether the error is caused by an instance accessing Manager or not. Since other scenarios that may cause this error are unknown, I assume that you have somehow mixed 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 should 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 instances. See the documentation for obtaining objects for more details. Money quote:

Managers are only available through model classes, not from model instances, to ensure separation between table-level operations and record-level operations.

(emphasis added)

Update

See comments from @ Daniel below. It is a good idea (no, you MUST: P) use a header for class names. For example topic instead of topic . Class names cause some confusion as to whether you are referencing an instance or class. Since Manager isn't accessible via <model> instances very specific, I can offer a solution. The error may not always be obvious.

+93
Oct 06 2018-10-06
source share
 topic.__class__.objects.get(id=topic_id) 
+39
Oct. 16
source share

For django <1.10

 topic._default_manager.get(id=topic_id) 

Although you should not use it like that. _default_manager and _base_manager are private, so it is recommended to use them only if you are inside the Theme model, for example, when you want to use the Manager in your own function, 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', ...] 
+31
Apr 11 '12 at 17:40
source share

It can also be called in pairs of brackets, for example,

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

instead of the right

 ModelClass.objects.filter(...) 

It happens to me sometimes when bpython (or IDE) automatically adds parentheses.

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

+3
Jan 20 '16 at 12:44
source share

I just had a problem similar to this error. And looking back at your code, it seems like this might be your problem too. I think your problem is that you are comparing "id" with "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 assume your code should use "post_id" and not "topic_id"

 def test(request, post_id): post = topic.objects.get(id = int(post_id)) post.delete() 
0
Jan 19 '19 at 6:07
source share

If the theme was an instance of ContentType (this is not the case), this would work:

 topic.model_class().objects.filter(forum = forum) 
-one
Jun 09 '13 at 18:09
source share



All Articles