Ситуация
У нас есть несколько различных приложений, которые используют тикеты из системы поддержки тикетов для различных функций.
Во-первых, у нас есть приложение, в котором есть несколько моделей, представляющих модели нашей системы поддержки билетов Kayako. Это приложение не должно ничего знать о других приложениях, которые его используют, и должно оставаться как можно более универсальным. Поскольку это приложение использует существующие таблицы Kayako, оно работает в той же базе данных. Назовем это приложение kayakodb.
Одно приложение связывает клиентов из нашей базы данных клиентов с заявками в системе поддержки заявок. Ранее эта система имела собственное представление заявок внутри нашей системы поддержки заявок, запрашивая заявки с помощью API, предоставленного kayakodb. Затем он использовал это представление билетов, чтобы связать клиентов и домены. Однако это было слишком сложно и не очень логично. Поэтому мы решили переключить его на прокси-модель и переместить модели, представляющие ссылки на клиентов и домены, в kayakodb. Назовем это приложение sidebar.
Другое, новое приложение, показывает заявки из системы поддержки заявок в четком обзоре вместе со звонками, чтобы наш отдел поддержки мог легко увидеть, какие звонки и заявки связаны с какими клиентами. Эта система имеет прокси-модель для прокси-модели sidebar, потому что некоторые функции, предоставляемые моделью sidebar, также требуются для этого приложения наряду с некоторыми другими, объявленными новой прокси-моделью. Назовем этот проект WOW.
Приложения sidebar и WOW являются частью одного и того же проекта/репозитория. Мы назовем этот репозиторий Coneybeach, у которого есть собственная база данных. Однако kayakodb — совершенно не связанный с этим проект. Он включен в Coneybeach через файл требований, который мы устанавливаем через pip.
Проблема
При создании миграции для новой установки Django создает миграцию прокси-модели для установленного
kayakodb, что, конечно же, не подходит. Каждый раз, когда мы устанавливали новую версию kayakodb, она перезаписывала эту миграцию. Не говоря уже о том, что kayakodb ничего не должен знать о том, какие модели его используют.
Код
Модель
Ticket внутри kayakodb:
class Ticket(models.Model):
"""
This model is a representation of the data stored in the "kayako" database table "swtickets". Minus a lot of stuff
we don't use. If you add a field make sure it has the same name as the field in kayako.swtickets.
"""
# Fields, functions and manager etc.
class Meta:
db_table = 'swtickets'
managed = False
Прокси-модель SidebarTicket внутри sidebar:
from kayakodb.models import Ticket
class SidebarTicket(Ticket):
class Meta:
# Since this class is a wrapper we don't want to create a table for it. We only want to access the original
# model as we always do, but provide a different interface (when it comes to functions). Proxy models allow us
# to do this: https://docs.djangoproject.com/en/1.10/topics/db/models/#proxy-models
proxy = True
# Don't look for this model in the sidebar tables, but in the kayakodb tables.
app_label = 'kayakodb'
# Some extra functions
Класс Contact TicketWrapper наследуется от (по запросу Hynekcer). Эта модель используется в качестве базовой модели для TicketWrapper и другой модели, представляющей вызовы (хотя, насколько мне известно, с этой моделью нет проблем):
class Contact(models.Model):
type = None
class Meta:
abstract = True
def __getattr__(self, attr):
if attr in ['customers', 'add_customer_id', 'remove_all_customers', 'byters', 'domainnames', 'add_domain_name',
'remove_domain_name', 'add_text', 'remove_text', 'texts', 'creation_date', 'add_tag', 'get_tags',
'remove_tag', 'identifier']:
raise NotImplementedError('You should implement {}'.format(attr))
raise AttributeError(attr)
Прокси-модель TicketWrapper внутри WOW:
from sidebar.models import SidebarTicket
class TicketWrapper(Contact, SidebarTicket):
class Meta:
# Since this class is a wrapper we don't want to create a table for it. We only want to access the original
# model as we always do, but provide a different interface (when it comes to functions). Proxy models allow us
# to do this: https://docs.djangoproject.com/en/1.10/topics/db/models/#proxy-models
proxy = True
# Don't look for this model in the WOW database, but in the kayakodb database.
app_label = 'kayakodb'
# Some extra functions
Что я пробовал
- Я пытался не указывать
app_labelдля обеих моделей прокси. Это создает правильные миграции, но заставляет прокси-модели искать модельkayakodb.Ticketв базе данных Coneybeach. - Я пытался указать
abstract = Trueдля подклассов, но не был уверен, что это так, потому что я все еще хочу использовать менеджер для моделей. - Я рассматривал возможность переноса миграции, которая создается в настоящее время, в фактический проект
kayakodb, но я не думаю, что это хорошее решение.kayakodbничего не должен знать о реализации своих моделей или о том, где они используются. ./manage.py checkвозвращает 0 задач.
Вопрос
Как создать прокси-модель для модели, расположенной в другой базе данных или проекте?
Редактировать
После установки неуправляемой модели
kayakodb.Ticket проект WOW пытается создать миграцию для всех моделей в kayakodb. Результат:
Migrations for 'sidebar':
0004_auto_20170116_1210.py:
- Delete model Ticket
Migrations for 'kayakodb':
0001_initial.py:
- Create model Staff
- Create model Tag
- Create model Ticket
- Create model TicketPost
- Create model TicketTag
- Create model TicketCustomer
- Create model TicketDomain
- Create proxy model SidebarTicket
- Alter unique_together for ticketdomain (1 constraint(s))
- Alter unique_together for ticketcustomer (1 constraint(s))
- Create proxy model TicketWrapper
python manage.py check. Второстепенная важная проблема заключается в том, сколько баз данных используется и для них правильные маршрутизаторы db. - person hynekcer   schedule 14.01.2017KayakoTicket- это простоkayakodb.Ticket, но импортированный с операторомas. Я добавлю определение классаContact. Единственными моделями, которые должны иметь таблицы, представляющие их, являются модели в проектеkayakodb. К вашему сведению,./manage.py checkвозвращает 0 ошибок или предупреждений (Django 1.9.10). - person Bono   schedule 16.01.2017