Диспетчер недоступен через экземпляры модели
Я пытаюсь получить экземпляр объектов модели в другом. И я поднимаю эту ошибку :
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
5 ответов
ошибка, о которой идет речь, возникает при попытке доступа к 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
доступны только через классы моделей, а не из экземпляров модели, чтобы обеспечить разделение между "на уровне таблицы" операции и "записи" операций.
(Курсив)
обновление
см. комментарии от @Daniel ниже. Это хорошая идея (нет, вы должны :P) использовать регистр заголовка для имен классов. Например,Topic
вместо topic
. Ваши имена классов вызывают некоторую путаницу, ссылаетесь ли вы на экземпляр или класс. С Manager isn't accessible via <model> instances
очень специфичен, я могу предложить решение.Ошибка может быть не такой самоочевидно всегда.
для django
topic._default_manager.get(id=topic_id)
хотя вы не должны использовать его, как это. _default_manager и _base_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', ...]
также может быть вызвано парой парантезов слишком много, например
ModelClass().objects.filter(...)
вместо правильного
ModelClass.objects.filter(...)
меня такое бывает, когда bpython (или IDE) автоматически добавляет parantheses.
результат, конечно, тот же - у вас есть экземпляр, а не класс.
если бы тема была экземпляром ContentType (которого нет), это сработало бы:
topic.model_class().objects.filter(forum = forum)