No se puede acceder al administrador a través de instancias de modelo

3 minutos de lectura

Avatar de usuario de ThomasDurin
ThomasDurin

Estoy tratando de obtener una instancia de objetos modelo en otra y me aparece este error:

No se puede acceder al administrador a través de la instancia del tema

Aquí está mi modelo:

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()

Aquí está mi vista:

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

Y obtengo:

post.delete()
forum.topic_count = topic.objects.filter(forum = forum).count()
Manager isn't accessible via topic instances

  • necesita usar Tema (nombre de clase) para acceder a objetos (Administrador). como se menciona en la documentación de Django (solo se puede acceder a los administradores a través de clases de modelo, en lugar de instancias de modelo, para imponer una separación entre las operaciones de “nivel de tabla” y las operaciones de “nivel de registro”).

    – emir jj

    11/11/2022 a las 17:00


Avatar de usuario de Manoj Govindan
Manoj Govindan

El error en cuestión se produce cuando intenta acceder a la Manager de un modelo a través de una instancia del modelo. has usado minúscula nombres de clases Esto hace que sea difícil decir si el error es causado por una instancia que accede al Manager O no. Dado que se desconocen otros escenarios que pueden causar este error, asumo que de alguna manera ha confundido el topic variable para que termine apuntando a una instancia de la topic modelo en lugar de la clase.

Esta línea es la culpable:

forum.topic_count = topic.objects.filter(forum = forum).count()
#                   ^^^^^

Tienes que usar:

forum.topic_count = Topic.objects.filter(forum = forum).count()
#                   ^^^^^
#                   Model, not instance.

¿Qué está yendo mal? objects es un Manager disponible a nivel de clase, no a las instancias. Ver el documentación para recuperar objetos para detalles. Cotización de dinero:

Managers son accesibles solo a través de clases de modelo, en lugar de instancias de modelo, para imponer una separación entre las operaciones de “nivel de tabla” y las operaciones de “nivel de registro”.

(Énfasis añadido)

Actualizar

Vea los comentarios de @Daniel a continuación. Es una buena idea (no, DEBE :P) usar mayúsculas y minúsculas para los nombres de las clases. Por ejemplo Topic en lugar de topic. Los nombres de sus clases causan cierta confusión, ya sea que se refiera a una instancia o una clase. Desde el Manager isn't accessible via <model> instances es muy específico, puedo ofrecer una solución. El error puede no ser tan evidente siempre.

  • Sin embargo, topic parece ser la clase de modelo real, y no una instancia de acuerdo con el código que proporcionó.

    – Daniel Di Paolo

    6 oct 2010 a las 16:16

  • @Daniel: cierto. Y sin embargo el error Manager isn't accessible via Foo instances solo es posible cuando intentas acceder a un Manager utilizando una instancia. Ver el código fuente: code.djangoproject.com/svn/django/trunk/django/db/models/…

    – Manoj Govindan

    6 de octubre de 2010 a las 16:18


  • De hecho, quizás otra razón (aparte de “es la mejor práctica”) para no usar letras minúsculas para los nombres de clase 🙂 Parece que está usando potencialmente topic como una variable de instancia local y eliminando la referencia a la clase.

    – Daniel Di Paolo

    6 de octubre de 2010 a las 16:19

  • deberías haber usado topic.model_class().objects

    – Nimo

    9 junio 2013 a las 18:10

  • También podrías usar topic.__class__.objects. Parecería model_class() mencionado por @Nimo arriba no funciona

    – Sleepy Cal

    13 de marzo de 2014 a las 16:23

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

  • Funciona a partir de Django v1.10.

    – Jaime

    8 de febrero de 2017 a las 20:24

  • Este __class__ también funciona mejor para métodos dentro de modelos abstractos, ya que no conocemos el nombre real de la clase descendiente. En esta situación, usé self.__class__.objects.get

    – Canto del cometa

    7 junio 2018 a las 17:36

  • Funciona increíble en un models.py modelo. def get_object(self): return self.__class__.objects.get(...). Usando esto para un GenericForeignKey.

    – Jarad

    18 oct 2021 a las 19:39

avatar de usuario de mihaicc
mihaicc

Para django

topic._default_manager.get(id=topic_id)

Aunque no deberías usarlo así. _default_manager y _base_manager son privados, por lo que se recomienda usarlos solo si está dentro del modelo Topic, como cuando desea usar el Administrador en una función propietaria, digamos:

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', ...]

  • Gracias, esta respuesta era justo lo que había estado buscando. Ojalá pudiera votar más de una vez. Mi caso de uso para esto es cuando está agregando funcionalidad a un modelo abstracto, donde no sabrá (en este nivel) cómo se llama la clase del modelo final.

    – abeja desvanecida

    20 de mayo de 2012 a las 6:11

  • O usar topic.__class__.objects.get(id=topic_id).

    – Bentley4

    7 oct 2013 a las 12:40

  • Esta es una respuesta antigua, pero a partir de Django v1.10 ya no veo estos métodos privados. Sin embargo, self.__class__.objects funciona según tu otra respuesta.

    – Jaime

    8 de febrero de 2017 a las 20:23

También podría ser causado por un par de paréntesis demasiado, por ejemplo

ModelClass().objects.filter(...)

en lugar de lo correcto

ModelClass.objects.filter(...)

Me pasa a veces cuando bpython (o un IDE) automáticamente agrega paréntesis.

El resultado, por supuesto, es el mismo: tiene una instancia en lugar de una clase.

Avatar de usuario de Nimo
nimo

si el tema fuera una instancia de ContentType (que no lo es), esto habría funcionado:

topic.model_class().objects.filter(forum = forum)

  • model_class() es un método de la ContentType modelo. Otras instancias modelo, incluyendo topicno tiene un model_class método.

    – Alasdair

    9 de junio de 2013 a las 19:36

  • Lo siento, debo haber leído mal la pregunta. Estaba tratando de resolver una pregunta aparentemente similar…

    – Nimo

    16 de junio de 2013 a las 15:39

avatar de usuario de brianwaganer
brianwaganer

Acabo de tener un problema similar a este error. Y mirando hacia atrás en su código, parece que también podría ser su problema. Creo que su problema es que compara “id” con “int (topic_id)” y topic_id no está configurado.

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

Supongo que su código debería usar “post_id” y no “topic_id”

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

  • model_class() es un método de la ContentType modelo. Otras instancias modelo, incluyendo topicno tiene un model_class método.

    – Alasdair

    9 de junio de 2013 a las 19:36

  • Lo siento, debo haber leído mal la pregunta. Estaba tratando de resolver una pregunta aparentemente similar…

    – Nimo

    16 de junio de 2013 a las 15:39

Kai - Avatar de usuario de Kazuya Ito
Kai-Kazuya Ito

Recibí el mismo error a continuación:

AttributeError: no se puede acceder al administrador a través de instancias de CustomUser

cuando accedí Manager con request.user.objects Como se muestra abajo:

"views.py"

from django.http import HttpResponse

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

¿Ha sido útil esta solución?