Slava Bugz
Slava Bugz

Reputation: 448

Different types of models into a django field

Is there an option to create a field that can contain a list of different types of other models? For example we have 3 models (Man,Woman,Child), and a field that can containt a list of them? So that i could for example do something like Human.var.add(Woman), Human.var.add(Man), Human.var.add(Child).

(and this field should containt many of them, var containt many of them).

Real example:

class Man(models.Model):
    name = models.Cha....
    age = models.Inte.....

class Woman(models.Model):
    name = models.Cha....
    age = models.Inte.....

class Child(models.Model):
    name = models.Cha....
    age = models.Inte.....


class Family(models.Model):
    people = *This field should take a list of Man, Woman Child, or a few of each*

Upvotes: 1

Views: 371

Answers (1)

dani herrera
dani herrera

Reputation: 51665

Instead of store people on family, the canonical design is to reference family from people:

from django.db import models
from model_utils.managers import InheritanceManager


class Family(models.Model):
    pass

class Person(models.Model):
    name = models.CharField(max_length=10)
    age = models.IntegerField()
    family = models.ForeignKey(Family, related_name="people", on_delete=models.PROTECT)
    objects = InheritanceManager()

    def __str__(self):
        return self.name

class Man(Person): # <--- Important part, inheritance
    pass # be free to extend subclasses with more fields

class Woman(Person):
    pass

class Child(Person):
    pass

Notice, for my convenience, I use inheritance manager from django-model-utils. But it's not mandatory if you don't need to select subclasses.

Here creating people and getting people from a family:

from people.models import Family, Man, Woman, Child

# first, we create a family
family=Family.objects.create()

# then, we assign people to the family
man=Man.objects.create(name="Daddy Pig", age=50, family=family)
woman=Woman.objects.create(name="Mummy Pig", age=50, family=family)
child=Child.objects.create(name="George", age=5, family=family)

# finally, we ask for family people. Here the more beautiful part:
family.people.select_subclasses()

Result:

<InheritanceQuerySet [<Man: Daddy Pig>, <Woman: Mummy Pig>, <Child: George>]>

Also take a look to Generic Relations because is related with this topic.

Upvotes: 2

Related Questions