在查询集中的 m2m 字段上混淆字段访问

问题描述

我有一个包含多个模型的 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 (将#修改为@)

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...