В моем приложении у меня есть две модели:
- 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, где я могу делегировать реализации каждой функции каждой модели?