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

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

 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

7 ответов

Решение

Данная ошибка возникает при попытке доступа к 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)

Для Джанго < 1,10

topic._default_manager.get(id=topic_id)

Хотя вы не должны использовать это так. _Default_manager и _base_manager являются частными, поэтому рекомендуется использовать их, только если вы находитесь внутри модели Topic, например, когда вы хотите использовать 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) автоматически добавляет паразиты.

Результат, конечно, тот же - у вас есть экземпляр вместо класса.

У меня просто была проблема, похожая на эту ошибку. И, оглядываясь на ваш код, кажется, что это тоже может быть вашей проблемой. Я думаю, что ваша проблема в том, что вы сравниваете "id" с "int(topic_id)" и topic_id не установлено.

def test(request, post_id):
    post = topic.objects.get(id = int(topic_id))
    post.delete()

Я предполагаю, что ваш код должен использовать "post_id", а не "topic_id"

def test(request, post_id):
    post = topic.objects.get(id = int(post_id))
    post.delete()

Я получил ту же ошибку ниже:

AttributeError: менеджер недоступен через экземпляры CustomUser

Когда я получил доступManagerсrequest.user.objectsкак показано ниже:

      "views.py"

from django.http import HttpResponse

def test(request):
    print(request.user.objects)
    return HttpResponse("Test")

Если бы тема была экземпляром ContentType (а это не так), это сработало бы:

topic.model_class().objects.filter(forum = forum)
Другие вопросы по тегам