j'essaie d'obtenir une instance d'objets de modèle dans une autre. Et je soulève cette erreur:
Manager isn't accessible via topic instance
Voici mon modèle:
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()
Voici mon point de vue:
def test(request, post_id):
post = topic.objects.get(id = int(topic_id))
post.delete()
Et je reçois:
post.delete()
forum.topic_count = topic.objects.filter(forum = forum).count()
Manager isn't accessible via topic instances
L'erreur en question est provoquée lorsque vous essayez d'accéder à la Manager
d'un modèle via une instance du modèle. Vous avez utilisé noms de classe en minuscule. Cela rend difficile de dire si l'erreur est provoquée par une instance accédant à la variable Manager
ou non. Etant donné que les autres scénarios pouvant causer cette erreur sont inconnus, je pars du principe que vous avez mélangé la variable topic
de sorte que vous finissiez par pointer vers une instance du modèle topic
au lieu de la classe.
Cette ligne est le coupable:
forum.topic_count = topic.objects.filter(forum = forum).count()
# ^^^^^
Vous devez utiliser:
forum.topic_count = Topic.objects.filter(forum = forum).count()
# ^^^^^
# Model, not instance.
Qu'est-ce qui ne va pas? objects
est une Manager
disponible au niveau de la classe, pas pour les instances. Consultez la documentation relative à la récupération d'objets pour plus de détails. Devis d'argent:
Managers
sont accessibles uniquement via les classes de modèle, et non à partir d'instances de modèle, pour imposer une séparation entre les opérations "au niveau de la table" et les opérations au niveau de l'enregistrement.
(Soulignement ajouté)
Mettre à jour
Voir les commentaires de @Daniel ci-dessous. C'est une bonne idée (non, vous DEVEZ: P) d'utiliser la casse de titre pour les noms de classe. Par exemple, Topic
au lieu de topic
. Vos noms de classe créent une certaine confusion, que vous parliez d'une instance ou d'une classe. Étant donné que le Manager isn't accessible via <model> instances
est très spécifique, je suis en mesure de proposer une solution. L’erreur peut ne pas toujours être aussi évidente.
topic.__class__.objects.get(id=topic_id)
Pour Django <1.10
topic._default_manager.get(id=topic_id)
Bien que vous ne devriez pas l'utiliser comme ça. _Default_manager et _base_manager sont privés. Il est donc recommandé de les utiliser uniquement si vous vous trouvez dans le modèle Topic, comme lorsque vous souhaitez utiliser le gestionnaire dans une fonction propriétaire, par exemple:
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', ...]
Peut aussi être causé par une paire de parenthèses trop lourde, par ex.
ModelClass().objects.filter(...)
au lieu du correct
ModelClass.objects.filter(...)
Cela m’arrive parfois lorsque bpython (ou un IDE) ajoute automatiquement des parenthèses.
Bien entendu, le résultat est identique: vous avez une instance au lieu d'une classe.
si topic était une instance de ContentType (ce qui n'est pas le cas), cela aurait fonctionné:
topic.model_class().objects.filter(forum = forum)
Je viens d'avoir un problème similaire à cette erreur. Et en regardant votre code, il semble que cela pourrait également être votre problème. Je pense que votre problème est que vous comparez "id" à "int (topic_id)" et topic_id n'est pas défini.
def test(request, post_id):
post = topic.objects.get(id = int(topic_id))
post.delete()
Je suppose que votre code devrait utiliser "post_id" et non "topic_id"
def test(request, post_id):
post = topic.objects.get(id = int(post_id))
post.delete()