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

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

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


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)