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:
- both customers and suppliers should have their "user" address, so should be in Profile
- customers also have a billing address, should be in Customer then
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)
开发者_JAVA百科 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
- groups the address data nicely behind one field instead of "polluting" the model
- no risk of multiple inheritance in future
Inheritance
- easier access to fields
- fewer database joins
- addresses are automatically visible with the object in Django's admin
Which one would you go with and why? Do you think either of the solutions is inherently bad? Do you see some better alternatives?
I would probably go with the Foreign Key approach - I think it's cleaner.
Dealing with the "pros" of inheritance you list:
- It's easy to access fields belonging to an object that is Foreign Keyed -
my_customer.address.zipcode
isn't too hard, is it? - I doubt you'll find joins prohibitively expensive, and if you do you can always avoid them when fetching lots of Customers/Suppliers.
- You can always display addresses alongside the object in Django's admin if you define a
__unicode__()
method onAddress
, and just addaddress
(if that's what you call the ForeignKey property ofCustomer
) to your admin'slist_display
.
精彩评论