Django: модели наследования или интерфейс для обмена функциями между различными моделями? - PullRequest
0 голосов
/ 16 октября 2018

В моем приложении у меня есть две модели:

  • A: веб-сайты, созданные моей компанией
  • B: веб-сайты, созданные третьей стороной

Моя цель - выяснить, должны ли A и B иметь общего предка через унаследованный образец модели или они должны реализовывать один и тот же интерфейс.

Это определение A:

class A(models.Model):
    is_ready = models.BooleanField(default=False, verbose_name=_('Ready?'))
    is_abandoned = models.BooleanField(default=False, verbose_name=_('Abandoned?'))

    external_id = models.CharField(max_length=L, unique=True,
                                   validators=[validate_external_id])
    dns = models.CharField(max_length=100, blank=True, null=True)
    ip_address = models.CharField(max_length=15, blank=True, null=True,
                                  validators=[validate_ip_address])
                                           validators=[validate_woo_commerce_secret])
    domain = models.CharField(max_length=L, blank=True, null=True)

    geo = models.CharField(max_length=L, blank=True, null=True)
    vertical = models.CharField(max_length=L, blank=True, null=True)

    last_synced_by = models.ForeignKey(settings.AUTH_USER_MODEL,
                                       related_name='synced_by',
                                       on_delete=models.SET_NULL, blank=True, null=True)
    last_synced_at = models.DateTimeField(blank=True, null=True)
    last_synced_task_id = models.UUIDField(blank=True, null=True)

    styled_by = models.ForeignKey(settings.AUTH_USER_MODEL,
                                  related_name='designer',
                                  on_delete=models.SET_NULL, blank=True, null=True)
    is_styling_approved = models.NullBooleanField(blank=True, null=True)
    inspected_by = models.ForeignKey(settings.AUTH_USER_MODEL,
                                     related_name='inspector',
                                     on_delete=models.SET_NULL, blank=True, null=True)

    cloudflare_login = models.CharField(max_length=L, blank=True, null=True)
    cloudflare_password = models.CharField(max_length=L, blank=True, null=True)
    cloudflare_ns1 = models.CharField(max_length=L, blank=True, null=True)
    cloudflare_ns2 = models.CharField(max_length=L, blank=True, null=True)
    cloudflare_zone_id = models.CharField(max_length=64, blank=True, null=True,
                                          validators=[validate_cloudflare_zone_id])
    cloudflare_api_key = models.CharField(max_length=64, blank=True, null=True,
                                          validators=[validate_cloudflare_api_key])

    business = models.OneToOneField(Business, on_delete=models.SET_NULL,
                                    blank=True, null=True, related_name='instance')
    articles = models.ManyToManyField(Article, blank=True)
    products = models.ManyToManyField(Product, blank=True)
    plugins = models.ManyToManyField(Plugin, blank=True)

    connection_info = models.ForeignKey(ConnectionInfo, on_delete=models.SET_NULL,
                                        blank=True, null=True)

    offer = models.ForeignKey(Offer, on_delete=models.SET_NULL, blank=True, null=True)
    lander = models.ForeignKey(Lander, on_delete=models.SET_NULL, blank=True, null=True)

    last_deployed_by = models.ForeignKey(settings.AUTH_USER_MODEL,
                                         related_name='deployed_by',
                                         on_delete=models.SET_NULL, blank=True, null=True)
    last_deployed_at = models.DateTimeField(blank=True, null=True)
    last_deployed_task_id = models.UUIDField(blank=True, null=True)
    last_deployed_digest = models.CharField(max_length=32, blank=True, null=True)

    comment = models.TextField(blank=True, null=True)
    last_updated_at = models.DateTimeField(blank=True, null=True)

    account = models.OneToOneField(Account, blank=True, null=True,
                                   on_delete=models.SET_NULL, verbose_name=_('Account'))

    theme = models.CharField(max_length=L, blank=True, null=True)

    task_id_n2_create_node = models.UUIDField(blank=True, null=True)
    task_id_n2_configure_cf = models.UUIDField(blank=True, null=True)
    task_id_n2_expose_wp = models.UUIDField(blank=True, null=True)
    task_id_n2_setup_campaign = models.UUIDField(blank=True, null=True)
    task_id_n2_test = models.UUIDField(blank=True, null=True)

    n2_external_id = models.CharField(
        blank=True, null=True,
        unique=True,
        max_length=L, validators=[validate_external_id])
    n2_ip_address = models.CharField(
        blank=True, null=True,
        max_length=15, validators=[validate_ip_address])
    n2_dns = models.CharField(
        blank=True, null=True, max_length=100)

Это модельное определение B:

class Node(models.Model):
    safepage_url = models.URLField(blank=True, null=True)

    offer = models.ForeignKey(
        Offer, blank=True, null=True, on_delete=models.SET_NULL)
    lander = models.ForeignKey(
        Lander, blank=True, null=True, on_delete=models.SET_NULL)
    account = models.OneToOneField(
        Account, blank=True, null=True, on_delete=models.SET_NULL)
    domain = models.CharField(
        max_length=L, blank=True, null=True)
    external_id = models.CharField(
        blank=True, null=True, unique=True,
        max_length=L, validators=[validate_external_id])
    ip_address = models.CharField(
        blank=True, null=True,
        max_length=15, validators=[validate_ip_address])
    dns = models.CharField(
        blank=True, null=True, max_length=100)

    task_id_create_node = models.UUIDField(blank=True, null=True)
    task_id_setup_campaign = models.UUIDField(blank=True, null=True)
    task_id_verify_setup = models.UUIDField(blank=True, null=True)
  • И A, и B имеютсерия задач сельдерея, определенных для установки плагина.

    • A: CreateAWS, ConfigureCF, ExposeWP
    • B: CreateAWS, SetupNode, ManualVerify, PurchaseDomain
  • A и B реализуют свой "ShutdownView" довольноиначе:

    • A: ищет идентификатор AWS и завершает работу экземпляра
    • B: ищет стороннюю организацию, связанную с этим сайтом, и отправляет автоматическое электронное письмо.

Мы планируем добавить следующие функции к A и B:

  • Аналитика: рассчитать общее количество посетителей, доход закаждая А и В и т. д.

  • Большие данные: анализируйте рентабельность инвестиций для А и В в соответствии с их расходами на рекламу и т. д.

Как вы можетевидите, и A и B несколько похожи.Каждый из них реализует подобный интерфейс.

Я хочу создать функциональные возможности, которые работают на A и B, не заставляя их наследовать от одного и того же предка.

Существуют ли такие понятия, как интерфейс, определенный в Django, где я могу делегировать реализации каждой функции каждой модели?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...