Note that there are some explanatory texts on larger screens.

plurals
  1. PODjango ORM: caching and manipulating ForeignKey objects
    text
    copied!<p>Consider the following skeleton of a models.py for a space conquest game:</p> <pre><code>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() </code></pre> <p>I have many such data models for a project I'm working on, and I change the state of the game based on somewhat complicated interactions between various data objects. I want to avoid lots of unnecessary calls to the database, so once per turn, I do something like</p> <ol><li>Query all the fleets, planets, and other objects from the database and cache them as python objects</li> <li>Process the game objects, resolving the state of the game</li> <li>Save them back in the database</li> </ol> <p>This model seems to totally break down when using ForeignKey objects. For example, when a new fleet departs a planet, I have a line that looks something like this:</p> <pre><code>fleet.home.ships -= fleet.ships </code></pre> <p>After this line runs, I have other code that alters the number of ships at each of the planets, including the planet fleet.home. Unfortunately, the changes made in the above line are not reflected in the QuerySet of planets that I obtained earlier, so that when I save all the planets at the end of the turn, the changes to fleet.home's ships get overwritten.</p> <p>Is there some better way of handling this situation? Or is this just how all ORMs are?</p>
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload