anttikoo
anttikoo

Reputation: 815

Re-using set of model fields in Django

My site has two types of users; customers and suppliers. I have ended up with the following class structure:

class Customer(models.Model):
    # stuff specific to customers

class Supplier(models.Model):
    # stuff specific to suppliers

class Profile(models.Model):  # returned by Django's User.get_profile()
    user = models.ForeignKey(User, unique=True)
    customer = models.OneToOneField(Customer, null=True, unique=True)
    supplier = models.OneToOneField(Supplier, null=True, unique=True)

Now I need to add multiple addresses to these models:

Address would be something like:

class Address(models.Model):
    street1 = models.CharField(max_length=100)
    street2 = models.CharField(max_length=100)
    zipcode = models.CharField(max_length=16)
    city = models.CharField(max_length=100)
    state = models.CharField(max_length=100)
    country = models.CharField(max_length=100)

I can see two straightforward solutions to re-use the address information: either refer to Address via ForeignKey from Profile & Customer classes, or inherit Profile & Customer classes from Address.

I can see some pros for both approaches:

ForeignKey

Inheritance

Which one would you go with and why? Do you think either of the solutions is inherently bad? Do you see some better alternatives?

Upvotes: 1

Views: 384

Answers (1)

Dominic Rodger
Dominic Rodger

Reputation: 99811

I would probably go with the Foreign Key approach - I think it's cleaner.

Dealing with the "pros" of inheritance you list:

  1. It's easy to access fields belonging to an object that is Foreign Keyed - my_customer.address.zipcode isn't too hard, is it?
  2. I doubt you'll find joins prohibitively expensive, and if you do you can always avoid them when fetching lots of Customers/Suppliers.
  3. You can always display addresses alongside the object in Django's admin if you define a __unicode__() method on Address, and just add address (if that's what you call the ForeignKey property of Customer) to your admin's list_display.

Upvotes: 1

Related Questions