web-dev-qa-db-fra.com

django - get () a renvoyé plus d'un sujet

Quand j'ai essayé de relier un attribut à un autre qui a une relation M to M, j'ai reçu cette erreur:

get () a renvoyé plus d'un sujet - il en a renvoyé 2!

Pouvez-vous me dire ce que cela signifie et peut-être me dire à l'avance comment éviter cette erreur?

modèles

class LearningObjective(models.Model):
    learning_objective=models.TextField()

class Topic(models.Model):
    learning_objective_topic=models.ManyToManyField(LearningObjective)
    topic=models.TextField()

sortie de LearningObjective.objects.all()

[<LearningObjective: lO1>, <LearningObjective: lO2>, <LearningObjective: lO3>]

sortie de Topic.objects.all()

[<Topic: Topic object>, <Topic: Topic object>, <Topic: Topic object>, <Topic: Topic object>, <Topic: Topic object>, <Topic: Topic object>, <Topic: Topic object>, <Topic: Topic object>, <Topic: Topic object>, <Topic: Topic object>, <Topic: Topic object>, <Topic: Topic object>, <Topic: Topic object>, <Topic: Topic object>]

vues

 def create_themen(request):
     new_topic=Topic(topic=request.POST['topic'])
     new_topic.save()
     return render(request, 'topic.html', {'topic': topic.objects.all()})

 def create_learning_objective(request):
     new_learning_objective=LearningObjective(learning_objective=request.POST['learning_objective'])
     new_learning_objective.save()
     new_learning_objective_topic=Topic.objects.get(topic=request.POST['topic'])
     new_learning_objective_topic.new_learning_objective_topic.add(new_learning_objective)
     return render( request, 'learning_objective.html', {
                    'topic': Topic.objects.all(),
                    'todo': TodoList.objects.all(),
                    'learning_objective': LearningObjective.objects.all()
                  })
45
BoJack Horseman

get() a renvoyé plus d'un sujet - il en a renvoyé 2!

L'erreur ci-dessus indique que vous avez plus d'un enregistrement dans la base de données lié au paramètre spécifique que vous avez transmis lors de l'interrogation à l'aide de get (), comme

Model.objects.get(field_name=some_param)

Pour éviter ce type d'erreur à l'avenir, vous devez toujours effectuer une requête conformément à la conception de votre schéma. Dans votre cas, vous avez conçu une table avec une relation M2M. Il est donc évident qu'il y aura plusieurs enregistrements pour ce champ et c'est la raison pour laquelle vous obtenez l'erreur ci-dessus.

Ainsi, au lieu d'utiliser get(), vous devez utiliser filter (), qui renverra plusieurs enregistrements. Tel que

Model.objects.filter(field_name=some_param)

Veuillez lire comment faire des requêtes dans Django ici .

97
CrazyGeek

get() renvoie un seul objet. S'il n'y a pas d'objet existant à renvoyer, vous recevrez <class>.DoesNotExist. Si votre requête renvoie plusieurs objets, vous obtiendrez alors MultipleObjectsReturned. Vous pouvez vérifier ici pour plus de détails sur les requêtes get ().

De même, Django se plaindra si plusieurs éléments correspondent à la requête get (). Dans ce cas, elle déclenche MultipleObjectsReturned, qui est à nouveau un attribut de la classe de modèle elle-même.

M2M renverra n'importe quel nombre de requête auquel elle est liée. Dans ce cas, vous pouvez recevoir zéro, un ou plusieurs éléments avec votre requête.

Dans vos modèles, vous pouvez nous suivre:

for _topic in topic.objects.all():
    _topic.learningobjective_set.all()

vous pouvez utiliser _set pour exécuter une requête de sélection sur M2M. Dans le cas ci-dessus, vous filtrerez tous les learningObjectives liés à chaque sujet.

13
FallenAngel

Dans votre modèle Topic, vous autorisez plusieurs éléments à avoir le même champ topic. Vous en avez déjà créé deux avec le même.

topic=models.TextField(verbose_name='Thema')

Maintenant, lorsque vous essayez d'ajouter un nouveau learningObjective, vous semblez vouloir l'ajouter à un seul Topic qui correspond à ce que vous envoyez sur le formulaire. Puisqu'il y en a plus d'un avec le même topic champ get trouve 2, d'où l'exception.

Vous pouvez soit ajouter le learningObjective à toutes les rubriques contenant ce champ topic:

for t in topic.objects.filter(topic=request.POST['Thema']):
    t.learningObjectivesTopic.add(neuesLernziel)

ou restreignez le modèle Topic à un seul champ topic et continue à utiliser get, mais il se peut que ce ne soit pas ce que vous souhaitiez.

3
Yeray Diaz Diaz

J'ai eu le même problème et la solution était obj = ClassName.objects.filter()

3
Nitesh

Get est censé renvoyer, un et exactement un enregistrement, pour corriger cette utilisation filter() , puis utiliser le premier élément du jeu de requête renvoyé pour obtenir l'objet que vous attendiez de get, il serait également utile de vérifier si au moins un enregistrement est renvoyé avant d'extraire le premier élément afin d'éviter IndexError

2
lmc