djangodjango-modelsone-to-manydatabase-relations

How to express a One-To-Many relationship in Django?


I'm defining my Django models right now and I realized that there wasn't a OneToManyField in the model field types. I'm sure there's a way to do this, so I'm not sure what I'm missing. I essentially have something like this:

class Dude(models.Model):
    # 1 dude can have 0+ phone numbers
    numbers = models.OneToManyField('PhoneNumber')

class PhoneNumber(models.Model):
    number = models.CharField()

In this case, each Dude can have multiple PhoneNumbers, but the relationship should be unidirectional, in that I don't need to know from the PhoneNumber which Dude owns it, per se, as I might have many different objects that own PhoneNumber instances, such as a Business for example:

class Business(models.Model):
    numbers = models.OneToManyField('PhoneNumber')

What would I replace OneToManyField (which doesn't exist) with in the model to represent this kind of relationship? I'm coming from Hibernate/JPA where declaring a one-to-many relationship was as easy as:

@OneToMany
private List<PhoneNumber> phoneNumbers;

How can I express this in Django?


Solution

  • To handle One-To-Many relationships in Django you need to use ForeignKey.

    The documentation on ForeignKey is very comprehensive and should answer all the questions you have:

    https://docs.djangoproject.com/en/3.2/ref/models/fields/#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).


    If you want the reverse relationship, you would need to add two ForeignKey fields to your PhoneNumber model, one to Dude and one to Business. This would allow each number to belong to either one Dude or one Business, and have Dudes and Businesses able to own multiple PhoneNumbers. I think this might be what you're after:

    class Business(models.Model):
        ...
    
    class Dude(models.Model):
        ...
    
    class PhoneNumber(models.Model):
        dude = models.ForeignKey(Dude)
        business = models.ForeignKey(Business)