Повторное использование набора полей модели в Django

У моего сайта есть два типа пользователей; клиентов и поставщиков. Я получил следующую структуру класса:

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)

Теперь мне нужно добавить несколько адресов к этим моделям:

  • и клиенты, и поставщики должны иметь свой «пользовательский» адрес, поэтому он должен быть в профиле.
  • у клиентов также есть адрес для выставления счетов, который должен быть в клиенте, тогда

Адрес будет примерно таким:

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)

Я вижу два простых решения для повторного использования адресной информации: либо обратиться к Address через ForeignKey из классов Profile & Customer, либо наследовать классы Profile & Customer из Address.

Я вижу некоторые плюсы для обоих подходов:

Иностранный ключ

  • хорошо группирует адресные данные за одним полем вместо того, чтобы «загрязнять» модель
  • отсутствие риска множественного наследования в будущем

Наследование

  • более легкий доступ к полям
  • меньше соединений с базой данных
  • адреса автоматически отображаются с объектом в админке Django

С кем бы вы пошли и почему? Считаете ли вы, что какое-либо из решений по своей сути плохо? Вы видите лучшие альтернативы?


person anttikoo    schedule 14.10.2010    source источник


Ответы (1)


Я бы, вероятно, выбрал подход с внешним ключом - я думаю, что он чище.

Говоря о «плюсах» наследования, вы перечисляете:

  1. Легко получить доступ к полям, принадлежащим объекту с внешним ключом — my_customer.address.zipcode не слишком сложно, не так ли?
  2. Я сомневаюсь, что вы обнаружите, что соединения непомерно дороги, и если вы это сделаете, вы всегда сможете избежать их при получении большого количества клиентов / поставщиков.
  3. Вы всегда можете отображать адреса рядом с объектом в панели администратора Django, если вы определяете метод __unicode__() для Address и просто добавляете address (если это то, что вы называете свойством ForeignKey для Customer) в list_display вашего администратора.
person Dominic Rodger    schedule 14.10.2010
comment
С административным аспектом я был в основном - person anttikoo; 14.10.2010
comment
Да, все еще изучаю этот материал... :-) Итак: хорошие моменты! Что касается административного аспекта, меня больше всего беспокоило представление на уровне объектов. Там было бы неплохо увидеть реквизиты адреса в раскрытом виде, а не втиснутые в одну строку. Я предполагаю, что этого можно добиться с помощью InlineModelAdmin, но все же это не так чисто, как с наследованием. - person anttikoo; 14.10.2010
comment
Вы всегда можете добавить части адреса в виде столбцов в вашем администраторе - например. добавьте address.zipcode к list_display вашего администратора. - person Dominic Rodger; 14.10.2010