Let's say I have a base class (Django model) called Character that looks something like
class Character(models.Model):
strength = models.blabla
dex = models.blabla
...
I can set that up with its attributes and hook it up to Admin and everything is lovely.
Then I decide I want a NonPlayerCharacter model, which has everything the Character model has, plus a new field or two. I can think of at least two ways to do this, each with pros and cons.
Option 1:
# The basic obvious stupid-simple answer is just to copy the model and add the fields
class NonPlayerCharacter(models.Model):
strength = models.blabla
dex = models.blabla
...
faction = models.blabla
Pros: Everything is kept very simple and easy to manage, and if the models need to diverge in the future, that's easy too.
Cons: Obvious code duplication and keeping universal changes in sync. If I change a stat or add a method on one, I've got to duplicate it on the other. If I add another type of Character, like Mob, well then it triples the upkeep to keep the necessary parts in sync.
Option 2:
# The next most obvious solution is to subclass Character
class NonPlayerCharacter(Character):
faction = models.blabla
Pros: I don't have to worry about keeping my classes in sync if I add something or make a change. Each is only concerned with its own NEW attributes and methods.
Cons: Everywhere I query for Character will also, by default, pull every subclass of Character. I'm (somewhat) aware of how to filter that out on a query-by-query basis, but it sure would be nice if Character.objects just got me characters and left the rest to queries for that particular model/subclass.
Is there a handy method to get the best of both worlds without filtering Character each time, or am I just asking something unreasonable?
Typically you can make an abstract base model, like:
class BaseCharacter(models.Model):
strength = models.blabla
dex = models.blabla
…
class Meta:
abstract = True
class Character(BaseCharacter):
pass
class NonPlayerCharacter(BaseCharacter):
faction = models.blabla