【发布时间】:2015-04-15 02:38:40
【问题描述】:
我正在尝试寻找最有效的方法来遍历我的模型以获取我想要的数据。我有三个“相关”模型。 Item、ProtectionList 和 Player
保护列表
class ProtectionList(models.Model):
player = models.ForeignKey(Player)
main_hand = models.ForeignKey(Item, null=True, blank=True, related_name='main_hand')
off_hand = models.ForeignKey(Item, null=True, blank=True, related_name='off_hand')
head = models.ForeignKey(Item, null=True, blank=True, related_name='head')
neck = models.ForeignKey(Item, null=True, blank=True, related_name='neck')
shoulder = models.ForeignKey(Item, null=True, blank=True, related_name='shoulder')
back = models.ForeignKey(Item, null=True, blank=True, related_name='back')
chest = models.ForeignKey(Item, null=True, blank=True, related_name='chest')
wrist = models.ForeignKey(Item, null=True, blank=True, related_name='wrist')
hands = models.ForeignKey(Item, null=True, blank=True, related_name='hands')
waist = models.ForeignKey(Item, null=True, blank=True, related_name='waist')
legs = models.ForeignKey(Item, null=True, blank=True, related_name='legs')
feet = models.ForeignKey(Item, null=True, blank=True, related_name='feet')
ring1 = models.ForeignKey(Item, null=True, blank=True, related_name='ring1')
ring2 = models.ForeignKey(Item, null=True, blank=True, related_name='ring2')
trinket1 = models.ForeignKey(Item, null=True, blank=True, related_name='trinket1')
trinket2 = models.ForeignKey(Item, null=True, blank=True, related_name='trinket2')
locked = models.BooleanField(default=False)
def __unicode__(self):
return self.player.main_character.name
播放器
class Player(models.Model):
accountID = models.CharField(max_length=255, null=True, blank=True)
battletag = models.CharField(max_length=255, null=True, blank=True)
user = models.OneToOneField(User, null=True, blank=True)
main_character = models.ForeignKey('Character', null=True, blank=True, related_name='main_character')
signature = models.TextField(null=True, blank=True)
def __unicode__(self):
return self.battletag
物品
class Item(models.Model):
'''Details individual data for each item on a loot table'''
name = models.CharField(max_length=255, null=True)
item_id = models.IntegerField(null=True)
dropped_by = models.ForeignKey(Boss)
warforgeable = models.BooleanField(default=True)
bonus_string = models.CharField(max_length=255, blank=True, null=True)
def __unicode__(self):
return self.name
我需要将我的方式映射回Player 以创建Player 对象列表,具体取决于谁在其ProtectedList 的任何字段中拥有Item。
我知道Item 与ProtectionList 和ProtectionList 与Player 相关,但是我想找到一种有效的方法来检查Item 是ProtectionList 对象中的ForeignKey 的所有字段被过滤的Item 可能位于任何字段中(减去player 和locked 字段)。
我考虑过使用 Q 对每个字段进行 OR,但我不确定这在更大的查询集上会有多优化。
我也在查看中间表并将模型更改为多对多。
【问题讨论】:
-
我认为您遇到了困难,因为您的模型错误。而不是所有这些外键,使用包含您当前用作字段名称的名称的中间表(Django 称之为“通过”模型)的多对多链接到项目一次。如果您这样做,您的查询将变得非常容易。
-
如果没有明确定义,我将如何引用该项目所在的插槽?
-
中间表(“通过”模型)允许您存储额外数据,可以是一个字符串字段,如
slot_name设置为一个值,例如“off_hand”或“main_hand”。现在您只需过滤与相关项目和字符匹配的 m2m 关系(通常通过查询“通过”模型),确定槽就像检查您最终以这种方式选择的对象上的 CharField 一样简单。 -
@NeilAshleyHickman 您可以在中间表中为插槽添加一个额外的字段。
-
我的 atm 时间很短,因此是 cmets。如果我稍后检查(我总是在上车时回顾我的活动)并且仍然什么都没有/你还没有弄清楚,我会尝试为此编写一个 SSCCE。 :)
标签: python django django-queryset models