Naftuli Kay
Naftuli Kay

Reputation: 91740

How should I define models that will be owned by many different models?

Disclaimer: Django models sometimes confuse the heck out of me.

I have the following situation, which I'll express in JPA as it makes the most sense to me:

@Entity
public class Address {
    /* fields omitted for brevity */
}

@Entity
public class User {
    @OneToMany
    private List<Address> addresses;
}

@Entity 
public class Location {
    @OneToOne
    private Address address;
}

@Entity
public class MultiEvent {
    @OneToMany
    private List<Address> addresses;
}

How would I express the following in Django:

  1. One User can have many Addresses, but Addresses don't need to have any reference back to their owner.
  2. One Location has one Address, but again, the Address doesn't need to have any reference back to its owner.
  3. Similar to the first scenario, one MultiEvent can have many Addresses, but each Address doesn't need to reference the MultiEvent that it belongs to.

How can I create the same scenario in Django? I get confused easily as there isn't a OneToMany field nor a ManyToOne field in Django, only the ForeignKey field. I also can't find the complete documentation for all accepted constructor parameters defined by ForeignKey which might explain why I'm feeling a bit lost.

Upvotes: 0

Views: 118

Answers (2)

dennmat
dennmat

Reputation: 2718

In django 'oneToMany' works out to ForeignKey. I find that using related names can help ease confusion in this sense:

#models.py
class myModel(Model):
    other_item = field(...)

class otherModel(Model):
    mymodel = ForeignKey(myModel, related_name="otherModels")

#then you can access all the otherModels as:
#the orm adds this attribute to any instantiated models of myModel
#its the equivalent of otherModel.objects.filter(mymodel=model_instance) 
myModelInstance.otherModels.all()

Unfortunately this means you always have to declare the relation in the "one" of the oneToMany relationship. But at the end of the day is proper database design.

Upvotes: 0

Roshan Mathews
Roshan Mathews

Reputation: 5898

One User can have many Addresses, but Addresses don't need to have any reference back to their owner.

You will need a foreign key in Address, pointing to a User. Give it a related_name so that you can refer to it in an intuitive way. Something like this,

class Address(models.Model):
    user = models.ForeignKey(User, related_name='addresses')

u = User()
for a in u.addresses.all(): 
    print a  # loop through all addresses

One Location has one Address, but again, the Address doesn't need to have any reference back to its owner.

Use a One to one relationship, the back reference you get for free!

Similar to the first scenario, one MultiEvent can have many Addresses, but each Address doesn't need to reference the MultiEvent that it belongs to.

Same as the first, ForeignKey in Address to 'MultiEvent`

Upvotes: 1

Related Questions