我只做了第一个,但应该都是类似的。我不能在直接查询中做到这一点,所以我不得不使用一些 python。
数据库中的数据输入
i1 = Instrument.objects.create(name="piano")
i2 = Instrument.objects.create(name="violin")
i3 = Instrument.objects.create(name="drums")
i4 = Instrument.objects.create(name="guitar")
i5 = Instrument.objects.create(name="bassoon")
w1 = MusicWork.objects.create(name="w1") # w1 contains extra instrument
w1.performers.add(i1, through_defaults={'quantity':1})
w1.performers.add(i2, through_defaults={'quantity':1})
w1.performers.add(i3, through_defaults={'quantity':1})
w2 = MusicWork.objects.create(name="w2") # w2 is the required work
w2.performers.add(i1, through_defaults={'quantity':1})
w2.performers.add(i2, through_defaults={'quantity':1})
w3 = MusicWork.objects.create(name="w3") # w3 has wrong quantities
w3.performers.add(i1, through_defaults={'quantity':2})
w3.performers.add(i2, through_defaults={'quantity':1})
MusicWorkInstrument.objects.all()
最后一行代码的输出是
<QuerySet[
<MusicWorkInstrument: w1-piano-1>,
<MusicWorkInstrument: w1-violin-1>,
<MusicWorkInstrument: w1-drums-1>,
<MusicWorkInstrument: w2-piano-1>,
<MusicWorkInstrument: w2-violin-1>,
<MusicWorkInstrument: w3-piano-2>,
<MusicWorkInstrument: w3-violin-1>
]>
获取所有与数量为 1 的钢琴乐器的作品
query1 = [i.work for i in MusicWorkInstrument.objects.filter(instrument__name="piano", quantity=1)]
query1
Out: [<MusicWork: w1>, <MusicWork: w2>]
获取所有作品与数量为 1 的小提琴乐器
query2 = [i.work for i in MusicWorkInstrument.objects.filter(instrument__name="violin", quantity=1)]
query2
Out: [<MusicWork: w1>, <MusicWork: w2>, <MusicWork: w3>]
获取包含任何数量的任何其他乐器的所有作品
excluding_list = [i.name for i in Instrument.objects.exclude(name__in=["piano","violin"])]
excluding_list
Out: ['drums', 'guitar', 'bassoon']
query3 = [ i.work for i in MusicWorkInstrument.objects.filter(instrument__name__in=excluding_list) ]
query3
Out: [<MusicWork: w1>]
前 2 个和第 3 个不同的交点会给出答案
query_final = ( set(query1) & set(query2 ) ).difference( set(query3) )
query_final
Out: {<MusicWork: w2>} # this is a set