Диспетчер не доступен через экземпляры модели
Я пытаюсь получить экземпляр объекта модели в другом. И я поднимаю эту ошибку:
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
Я могу предложить решение. Ошибка не всегда так очевидна.
Для Джанго < 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)