问题描述
我有一个包含多个模型的 django 项目。其中两个模型是:
class Attack(models.Model):
spell = models.ForeignKey("Spell",models.CASCADE,null=True)
attacker = models.ForeignKey("Ent",related_name='attacker')
defender = models.ForeignKey("Ent",related_name='defender')
defender_pts_before = models.IntegerField(default=0,blank=False,null=False)
damage_caused = models.IntegerField(default=0,null=False)
和
class Ent(models.Model):
name = models.CharField(max_length=50,null=False)
raze = models.CharField(max_length=50,null=False)
damage = models.CharField(max_length=50,null=False)
weakness = models.CharField(max_length=50,null=False)
health = models.FloatField(default=100,null=False)
attacks = models.ManyToManyField('self',through=Attack,symmetrical=False,related_name='attacked_from')
battles = models.ManyToManyField(Battle,through=BattleParticipant,related_name='battles_part')
如您所见,Ent
模型通过 Attack
模型对自身有一个 m2m 场。这是为了表示ents之间的攻击。攻击模型将攻击者对防御者造成的所有伤害存储在damage_caused
字段中(在保存攻击时计算)。
我需要知道每个实体在所有攻击中造成的总损失,因此我构建了以下查询:
Ent.objects.all().annotate(dmg=Sum('attacks__attacker__damage_caused'))
但这似乎不起作用。它似乎只能以正确的方式使用此查询:
Ent.objects.all().annotate(dmg=Sum('attacks__defender__damage_caused'))
测试
我创建了一些条目来检查查询(从一个实体到另一个实体的单一攻击)
In [106]: e1,e2 = Ent.objects.all().annotate(dmg=Sum('attacks__attacker__damage_caused'))[:2]
In [107]: e1,e2
Out[107]: (<Ent: Ent object (240)>,<Ent: Ent object (241)>)
In [108]: e1.attacks.all()
Out[108]: <QuerySet [<Ent: Ent object (241)>]>
In [109]: e2.attacks.all()
Out[109]: <QuerySet []>
如您所见,e1
只有一次攻击,而 e2
没有任何攻击。让我们看看这次攻击:
In [110]: atk = Attack.objects.filter(attacker=e1).first()
In [111]: atk.attacker
Out[111]: <Ent: Ent object (240)>
In [112]: atk.defender
Out[112]: <Ent: Ent object (241)>
In [113]: atk.damage_caused
Out[113]: 20
好吧,攻击者是e1
,防御者是e2
,但是当我检查注释值时:
In [114]: e1.dmg,e2.dmg
Out[114]: (None,None)
e1
的总伤害应该是 20,但两者都没有。当我执行以下查询时,奇怪的部分出现了:
In [115]: e1,e2 = Ent.objects.all().annotate(dmg=Sum('attacks__defender__damage_caused'))[:2]
In [116]: e1,e2
Out[116]: (<Ent: Ent object (240)>,<Ent: Ent object (241)>)
In [117]: e1.dmg,e2.dmg
Out[117]: (20,None)
如果我通过 defender
(而不是 attacker
)访问攻击,它会给我正确的答案。所以我在这里有点困惑。为什么会这样?
解决方法
暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!
如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。
小编邮箱:dio#foxmail.com (将#修改为@)