2015-08-10 3 views
2

У меня есть абстрактная модель:через модель для абстрактной модели

class Distributor(models.Model): 

    class Meta: 
     abstract = True 

и 2 модели, которые наследуют его:

class DistributorGroup(Distributor): 
    pass 

class DistributorPerson(Distributor): 
    pass 

также у меня есть LLink модель:

class Link(models.Model): 
    distributors_persons = models.ManyToManyField(
     'people.DistributorPerson', blank=True, related_name='distributors_persons_of_links') 
    distributors_groups = models.ManyToManyField(
     'groups.DistributorGroup', blank=True, related_name='distributors_groups_of_links') 

Ссылка может иметь отношение к одному из дистрибьюторов. Я выполнил это поведение, добавив 2 m2m и установив blank=True для обоих.

Теперь я понял, что мне нужна модель through для подключения Distributor s и Link. Но поскольку модель through не может иметь абстрактную модель как внешний ключ, я не знаю, что делать. Нужно ли создавать 2 отдельные модели through для DistributorPerson и DistributorGroup или есть способ сделать это с помощью модели 1 through. Также я не знаю, является ли мой 2 m2m в модели Link подходящим способом выполнить то поведение, которое я хочу.

Так что я хотел бы знать, как организовать эти модели m2m с абстрактной моделью.

ответ

2

Первый вопрос: действительно ли должны быть отдельные таблицы DistributorPerson и DistributorGroup. Если они очень похожи, может иметь смысл просто использовать одну таблицу. (Например, если вы моделировали номера телефонов, вы, вероятно, не использовали бы отдельные таблицы Home, Work и Mobile, вместо этого вы использовали бы одну таблицу с полем типа.)

(И обратите внимание, что вы можете использовать proxy models, чтобы разные модели Django могли использовать одну и ту же таблицу базы данных.)

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

class DistributorGroup(Distributor): 
    distributor_links = GenericRelation(DistributorLink, related_query_name="distributor_groups") 

class DistributorPerson(Distributor): 
    distributor_links = GenericRelation(DistributorLink, related_query_name="distributor_persons") 

class Link(models.Model): 
    pass 

class DistributorLink(models.Model): 
    link = models.ForeignKey(Link); 

    content_type = models.ForeignKey(ContentType) 
    object_id = models.PositiveIntegerField() 
    content_object = GenericForeignKey('content_type', 'object_id') 

Смотрите документацию на generic relations примеры и более подробно.

Наконец, если все остальное не удается, вы можете создать две отдельные таблицы M2M для двух видов отношений.

Обратите внимание, что это не имеет ничего общего с абстрактными моделями. Абстрактные модели - это всего лишь механизм повторного использования кода в Django, они не влияют на таблицы или запросы, которые вы запускаете на них.

+0

Благодарим вас за ответ! Вы ответили на один из моих вопросов, и теперь меня интересует другое. У меня не может быть ни одной таблицы для обоих дистрибьюторов, так как их функциональные возможности довольно разные, а также поля, но спасибо за показ других способов проектирования БД. Другой вопрос касается модели «сквозной». Если я останусь с моделями 2 m2m, мне нужно создать для каждого из них 'сквозную 'модель (они будут абсолютно одинаковыми)? – pythad

+0

@pythad: Да, но есть ли причина, по которой вы считаете, что вам нужны две таблицы M2M? (Я понимаю, что вам нужны две таблицы дистрибьютора.) Обратите внимание, что 'DistributorLink' выше * - * пользовательская таблица M2M, она просто не объявляется как таковая в' Link', потому что Django не предлагает эту опцию с родовыми отношениями. Сравните 'a_link.distributor_persons.all()' (ваш старый путь) с 'DistributorPerson.objects.filter (distributor_links = a_link)' (таким образом). –

+0

Я читал немного об этих родовых отношениях, я думал немного о них, теперь я понимаю, о чем вы говорите.Использование вашего кода - это способ реализации «сквозной» модели, такой же, как и обычный? – pythad

Смежные вопросы