Как моделировать кредитные позиции между группой компаний - PullRequest
2 голосов
/ 14 апреля 2011

У меня есть группа связанных компаний, которые делятся своими товарами друг с другом. У каждого предмета есть компания, которая владеет им, и компания, которая им владеет. Очевидно, что компания, которая владеет предметом, также может им владеть. Кроме того, компании иногда навсегда передают право собственности на предметы, а не просто одалживают их, поэтому я должен это учитывать.

Я пытаюсь решить, как моделировать владение и владение предметами. У меня есть стол Company и стол Item.

Вот варианты, которые я вижу:

  1. Inventory таблица с записями для каждого отношения Item - Company. Имеет поле company, указывающее на Company, и имеет логические поля is_owner и has_possession.
  2. Inventory таблица с записями для каждого Item. Имеет поле owner_company и поле possessing_company, каждое из которых указывает на Company.
  3. Две отдельные таблицы: ItemOwner и ItemHolder**.

Пока я склоняюсь к третьему варианту, но таблицы , поэтому похожи на дублирование. Вариант два будет иметь только одну строку для каждого элемента (в этом отношении он чище, чем первый вариант), но иметь два поля в одной таблице, которые оба ссылаются на таблицу Company, пахнет неправильно (и рисовать на диаграмме ER грязно! ).

Разработка базы данных - это не моя специальность (я в основном использовал нереляционные базы данных), поэтому я не знаю, какой будет наилучшая практика в этой ситуации. Кроме того, я новичок в Python и Django, так что может быть очевидная идиома или шаблон, который я пропускаю.

Каков наилучший способ смоделировать это без того, чтобы Company и Item не были загрязнены знанием владения и владения? Или я упускаю суть, желая сохранить свои модели такими раздельными? Что такое Pythonic путь?

Обновление

Я понял, что слишком много внимания уделяю проектированию баз данных. Было бы разумно просто написать хороший ОО-код и позволить ORM Джанго сделать это?

Ответы [ 3 ]

2 голосов
/ 14 апреля 2011

Есть ли причина, по которой вы не хотите, чтобы ваш товар содержал информацию о взаимоотношениях? Такое ощущение, что владелец и владелец являются атрибутами предмета.

class Company(models.Model):
    pass

class Item(models.Model):
    ...
    owner = models.ForeignKey(Company, related_name='owned_items')
    holder = models.ForeignKey(Company, related_name='held_items')

Некоторые примеры:

company_a = Company.objects.get(pk=1)

company_a.owned_items.all()
company_a.held_items.all()

items_owned_and_held_by_a=Items.objects.filter(owner=company_a, holder=company_a)

items_on_loan_by_a=Items.objects.filter(owner=company_a).exclude(holder=company_a)
#or
items_on_loan_by_a=company_a.owned_items.exclude(holder=company_a)

items_a_is_borrowing=Items.objects.exclude(owner=company_a).filter(holder=company_a)
#or
items_a_is_borrowing=company_a.held_items.exclude(owner=company_a)

company_b = Company.objects.get(pk=2)

items_owned_by_a_held_by_b=Items.objects.filter(owner=company_a, holder=company_b)
#or
items_owned_by_a_held_by_b=company_a.owned_items.filter(holder=company_b)
#or
items_owned_by_a_held_by_b=company_b.held_items.filter(owner=company_a)

Я думаю, что если ваши вещи принадлежат только одной компании и принадлежат одной компании, отдельная таблица не нужна. Если бы предметы могли иметь несколько владельцев или нескольких владельцев, было бы более разумно использовать таблицу m2m через таблицу инвентаря.

0 голосов
/ 14 апреля 2011

Вариант № 1, вероятно, самый чистый выбор. Предмет имеет только одну компанию-владельца и принадлежит только одной компании-владельцу.

Поместите два FK в Company в Item, и не забудьте явно определить related_name двух инверсий, чтобы они отличались друг от друга.

Поскольку вы хотите избежать прикосновения к модели Item, либо добавьте FK извне, как в field.contribute_to_class (), либо добавьте новую модель с равным отношением один к одному Item, а также внешние ключи.

Второй метод проще реализовать, но первый будет более естественным для использования после его реализации.

0 голосов
/ 14 апреля 2011
class Inventory(models.Model):
    REL = (('O','Owns'),('P','Possesses'))

    item = models.ForeignKey(Item)
    company = models.ForeignKey(Company)
    relation = models.CharField(max_length=1,choices=REL)

Может быть одной реализацией вместо использования логических значений.Так что я бы пошел на первое.Это может даже служить промежуточной таблицей, если вы когда-нибудь решите использовать «сквозной» для привязки предметов к компании, например:

Company:
    items = models.ManyToManyField(Item, through=Inventory)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...