I would like to create a model(1) with multiple foreign keys to the same other model(2).
I want these foreign keys to have the same related_name
because each foreign key will point to difference instances of model(2), because I need one reversed relation for all foreign keys.
Maybe an example will be more explicit :
class Parent(Model):
name = models.CharField(max_length=100)
class Child(Model):
name = models.CharField(max_length=100)
father = models.ForeignKey(Parent, related_name='children')
mother = models.ForeignKey(Parent, related_name='children')
How can I do that ?
I already know an ugly way to do so :
class Parent(Model):
name = models.CharField(max_length=100)
@property
def children(self):
# Pick the existing one in fields 'children_1' or 'children_2'
class Child(Model):
name = models.CharField(max_length=100)
father = models.ForeignKey(Parent, related_name='children_1')
mother = models.ForeignKey(Parent, related_name='children_2')
Your intermediate model must contain one - and only one - foreign key to the source model (this would be Group in our example). If you have more than one foreign key, a validation error will be raised.
The related_name attribute specifies the name of the reverse relation from the User model back to your model. If you don't specify a related_name, Django automatically creates one using the name of your model with the suffix _set. Syntax: field_name = models.Field(related_name="name")
To handle One-To-Many relationships in Django you need to use ForeignKey . The current structure in your example allows each Dude to have one number, and each number to belong to multiple Dudes (same with Business).
The related_names
can not be the same, since this would introduce confusion: an object that is related through the mother
is not (exactly) the same as an object related through the father
.
You can alter your modeling (for example by introducing a ManyToManyField
with the Parent
, and for example add extra data in the relation about the sex of the parent). But a disavantage of this approach is that now, you no longer set the cardinality of the relation to 2: it means a Child
can (by desing) have zero parents, one parent, two parents, three parents, or more. Furthermore it could be possible that a child has two mothers, or two fathers, or two mothers and three fathers. So it can result in a lot of extra logic to prevent certain cases. Note that in some countries that is possible: in some countries extra people can be listed as "parents", and they have the same legal rights and duties as a parent.
You can however define such property to obtain the children
, by making a query to fetch all Child
objects where the mother
, or the father
is self
:
from django.db.models import Q
class Parent(Model):
name = models.CharField(max_length=100)
@property
def children(self):
return Child.objects.filter(Q(mother=self) | Q(father=self))
You could for example name the related names 'father_of'
and 'mother_of'
such that you can query some_parent.mother_of
to obtain children where the some_parent
is the mother_of
. This could be useful if you for example would want to list a table with mothers and their children, or if you would make an application where it is possible that Parent
s change gender.
If you however want to have strict Father
s and Mother
s, then it might be beneficial to define two separate models. The advantage is that you can both name the related_name
s 'children'
then, and furthermore by design you check that the father
of a Child
is a male (and similar for a mother
being female).
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With