Диспетчер недоступен через экземпляры модели


Я пытаюсь получить экземпляр объекта модели в другом. И я поднимаю эту ошибку :

 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 57

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 очень конкретно я могу предложить решение.Ошибка может быть не такой самоочевидно всегда.

topic.__class__.objects.get(id=topic_id)

для 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)