pythondjangodatabasedjango-modelsorm

Making instances of Django records with a through model


Let's say you have a concept of a Battle, and in that battle there are Players and Enemies. The players are a simple ManyToMany, but Enemies require a Through model, because if there's a DB entry for "Goblin", players need to fight an INSTANCE of the Goblin model. Players may fight many Goblins, and each needs their own health/status at any given moment.

So far, I've got a Django model like so (I'm simplifying the code for readability, and to focus on the main issue)

class Battle(models.Model):
    players = ManyToMany(Player)
    enemies = ManyToMany(Enemy, through=EnemyThroughModel)

With the appropriate adjustments to admin.py and such, this works in that I can attach multiple Enemies to a Battle and see them listed separately in admin, HOWEVER, those are all keyed to the same basic Enemy, and if I change one of them (say, they take damage), ALL the keyed references to that enemy now have their health reduced.

Is there a neat way I can use through models to create a new instance of the enemies, so that they have independent health/mana/etc?


Solution

  • You need to set the health/mana of the enemy within the through model:

    class Player(models.Model):
        pass
    
    class EnemyType(models.Model):
        pass
    
    class EnemyInstance(models.Model):
        enemy_type = models.ForeignKey(EnemyType, on_delete=models.CASCADE)
        battle = models.ForeignKey('myapp.Battle', on_delete=models.CASCADE)
        mana = models.IntegerField()
        health = models.IntegerField()
    
    class Battle(models.Model):
        players = models.ManyToManyField(Player)
        enemies = models.ManyToManyField(EnemyType, through=EnemyInstance)
    

    That being said, relational DBs weren't designed to be used in this manner. You will need to read health/mana stats for players and enemies in real time, while the game in running. It would be better to store this data in memory, using a python object or another data structure (xml, json, etc). See How to choose how to store data? for a good starting point.