M to M関係を持つ別の属性と属性を関連付けようとしたときに、次のエラーが表示されました。
get()が複数のトピックを返しました-2を返しました!
どういう意味ですか、このエラーを回避する方法を事前に教えていただけますか?
モデル
_class LearningObjective(models.Model):
learning_objective=models.TextField()
class Topic(models.Model):
learning_objective_topic=models.ManyToManyField(LearningObjective)
topic=models.TextField()
_
LearningObjective.objects.all()
の出力
_[<LearningObjective: lO1>, <LearningObjective: lO2>, <LearningObjective: lO3>]
_
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>]
_
ビュー
_ 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()
})
_
get()
は複数のトピックを返しました-2を返しました!
上記のエラーは、次のようなget()を使用してクエリを実行中に渡した特定のパラメーターに関連するDBに複数のレコードがあることを示しています
_Model.objects.get(field_name=some_param)
_
将来この種のエラーを回避するには、スキーマ設計に従って常にクエリを実行する必要があります。あなたの場合、M2M関係でテーブルを設計したので、明らかにそのフィールドには複数のレコードがあり、それが上記のエラーを受け取っている理由です。
したがって、get()
を使用する代わりに、複数のレコードを返すfilter()を使用する必要があります。といった
_Model.objects.filter(field_name=some_param)
_
Django here でクエリを作成する方法についてお読みください。
get()
は、単一のオブジェクトを返します。返す既存のオブジェクトがない場合、<class>.DoesNotExist
を受け取ります。クエリが複数のオブジェクトを返す場合、MultipleObjectsReturned
を取得します。 get()クエリの詳細については、 here を確認してください。
同様に、Djangoは、get()クエリに複数のアイテムが一致した場合に文句を言います。この場合、モデルクラス自体の属性であるMultipleObjectsReturnedを発生させます。
M2Mは任意の数のクエリを返します それが関連しています。この場合、クエリでゼロ、1つまたは複数のアイテムを受け取ることができます。
あなたのモデルでは次のことができます:
for _topic in topic.objects.all():
_topic.learningobjective_set.all()
_set
を使用して、M2Mで選択クエリを実行できます。上記の場合、各トピックに関連するすべてのlearningObjective
sをフィルターします
Topic
モデルでは、複数の要素が同じtopic
フィールドを持つことを許可しています。同じもので2つを既に作成しました。
topic=models.TextField(verbose_name='Thema')
これで、新しいlearningObjective
を追加しようとすると、フォームで送信しているものと一致する1つのTopic
のみに追加したいようです。同じtopic
フィールドを持つ複数のget
が2を検出しているため、例外です。
learningObjective
フィールドを持つすべてのトピックにtopic
を追加できます。
for t in topic.objects.filter(topic=request.POST['Thema']):
t.learningObjectivesTopic.add(neuesLernziel)
またはTopic
モデルを一意のtopic
フィールドを持つように制限し、get
を使用し続けますが、それはあなたが望むものではないかもしれません。
私は同じ問題を抱えていましたが、解決策はobj = ClassName.objects.filter()
でした
Getは、この使用法を修正するために正確に1つのレコードを返すことになっています filter()
。また、IndexError
を避けるために、最初の要素を取り出す前に、少なくとも1つのレコードが返されるかどうかを確認すると便利です。