對於較小的集播放器/參與者,查找字典就夠了:
player_list = Player.objects.all()
# Get all relevant participants (or just all if you like)
player_ids = player_list.value_list('id', flat=True)
participant_list = Participant.objects.filter(player_id__in=player_ids)
# Create a lookup dict
participants = dict([(p.player_id, p) for p in participant_list])
# Everything is now prepared for quick access
for player in player_list:
if player.id in participants:
print participants[player.id].status
如果你經常這樣做,你可能需要使用不同的方法。這裏有三種選擇。
繼承
使用繼承並存儲在數據庫中的狀態。這將使類似的查詢在未來更容易/更高效:
class Player(models.Model):
name = models.CharField(max_length=128)
is_participant = models.BooleanField(default=False)
class Participant(Player):
status = models.CharField(max_length=32)
def save(self, *args, **kwargs):
if not self.id:
self.is_participant = True
super(Participant, self).save(*args, **kwargs)
有自己的數據結構類似,這意味着Participant
對象總是有相同的字段Player
對象和您可以檢查如果一個球員是一個參與者而不會觸及數據庫或循環遍歷所有參與者。但是,獲取相關參與者將遭受重創。這種方法的一個變種是將一個通用外鍵附加到Player
。檢查None
的屬性會告訴你玩家是否也是參與者,然後按照鏈接將您帶到相關的數據庫對象。
Denormalisation
如果狀態是你唯一需要的值,你可以將其存儲在播放器的模型太,並自動將其與你的Participant
值同步。如果你使用繼承如上,你會得到免費的:
class Player(models.Model):
name = models.CharField(max_length=128)
participant_status = models.CharField(max_length=32)
class Participant(Player):
pass
您可以查詢它是這樣的:
for player in Player.objects.all()
if player.participant_status:
print participant.status
一個缺點是,你將不得不隱藏播放器狀態字段形式。但好處是,你將能夠查詢a)如果玩家是參與者並且b)在沒有擊中數據庫的情況下獲得狀態。
但是這種設計當然不像標準化的數據庫那樣乾淨,只有在成本太高的情況下才能真正做到。
以一對一的關係
的最後一種方法是使用OneToOneField
如果是一對一的關係。理論上你可以從任何一方鏈接兩個模型,但我不確定這是如何與select_related()
一起工作的,這是你想用來避免在列表中多次觸擊數據庫的原因。
class Player(models.Model):
name = models.CharField(max_length=128)
participant = models.OneToOneField('Participant', null=True)
class Participant(models.Model):
status = models.CharField(max_length=32)
您的查詢是這樣的:
player_list = Player.objects.all().select_related('participant')
for player in player_list:
if player.participant_id is not None:
print player.participant.status
這不會做OP想要的。它將比較參與者1的參與者1,參與者2的參與者2等等。 OP希望比較每個參與者與每個參與者(即參與者1,2和3參與者1,然後參與者1,2和3參與者2)。再加上問題的陳述方式,這些名單很可能有不同的長度。 – Blair 2011-05-25 05:31:19
ohh,:D感謝您的更正 – Paulo 2011-05-25 05:48:24