次の宇宙征服ゲームの models.py のスケルトンを考えてみましょう:
class Fleet(models.Model):
game = models.ForeignKey(Game, related_name='planet_set')
owner = models.ForeignKey(User, related_name='planet_set', null=True, blank=True)
home = models.ForeignKey(Planet, related_name='departing_fleet_set')
dest = models.ForeignKey(Planet, related_name='arriving_fleet_set')
ships = models.IntegerField()
class Planet(models.Model):
game = models.ForeignKey(Game, related_name='planet_set')
owner = models.ForeignKey(User, related_name='planet_set', null=True, blank=True)
name = models.CharField(max_length=250)
ships = models.IntegerField()
私が取り組んでいるプロジェクトには、このようなデータ モデルが多数あり、さまざまなデータ オブジェクト間のやや複雑な相互作用に基づいてゲームの状態を変更します。データベースへの多くの不要な呼び出しを避けたいので、1ターンに1回、次のようにします
- データベースからすべての艦隊、惑星、およびその他のオブジェクトを照会し、それらを Python オブジェクトとしてキャッシュします
- ゲームオブジェクトを処理し、ゲームの状態を解決する
- それらをデータベースに保存します
このモデルは、ForeignKey オブジェクトを使用すると完全に崩壊するようです。たとえば、新しい艦隊が惑星を出発するとき、次のような行があります。
fleet.home.ships -= fleet.ships
この行が実行された後、惑星の艦隊を含む各惑星の船の数を変更する他のコードがあります。残念ながら、上記の行で行った変更は、以前に取得した惑星の QuerySet には反映されていないため、ターンの終わりにすべての惑星を保存すると、fleet.home の船への変更が上書きされます。
この状況を処理するためのより良い方法はありますか? それとも、これがすべての ORM のあり方ですか?