Почему Django создает файлы миграции для прокси-моделей?
Я только что создал модель прокси и был удивлен, что manage.py makemigrations
создает новый файл migrations.CreateModel
операцией migrations.CreateModel
.
Прокси-модель не создает новую таблицу базы данных, она просто представляет собой другой интерфейс Python для того же набора данных и действительно manage.py sqlmigrate my_app_label 0042
ничего не возвращает.
Я думал, что это может быть использовано для создания прокси-модели ContentType
но они создаются по требованию, если они не существуют.
Используется ли он для создания разрешений модели прокси? Есть 6-летняя открытая ошибка в разрешениях модели прокси, так что я не совсем уверен, как эта часть должна работать сейчас...
Он использовал Django 1.8
чтобы проверить это.
Редактировать: чтобы уточнить, Django
создает миграцию, которая ничего не делает для новых прокси-моделей, поэтому разве мы не хотим, чтобы Django
вообще не создавал миграцию, если она бесполезна?
Есть ли вариант использования, где было бы полезно провести миграцию?
Ответы
Ответ 1
Ах, но если вы откроете миграцию в своем редакторе, вы обнаружите, что это на самом деле пустая миграция! Вот пример
class Migration(migrations.Migration):
dependencies = [
('stackoverflow', '0009_auto_20160622_1507'),
]
operations = [
migrations.CreateModel(
name='MyArticle',
fields=[
],
options={
'proxy': True,
},
bases=('stackoverflow.article',),
),
]
И если вы запустите ./manage.py sqlmigrate myapp 0010
(это число, которое соответствует моей миграции выше), то вы получите то, что на следующей строке (ничего).
Это потому, что раздел fields
миграции пуст и option
включает в себя proxy = True
. Этот параметр предотвращает выполнение любого SQL
для этой миграции, и исходная таблица остается нетронутой.
Итак, вы можете спросить, почему Django
пытается создать пустую миграцию? Это потому, что на прокси-модель может ссылаться другая модель в будущей миграции.
Ответ 2
Я считаю, что migrations
генерируется, поскольку базы данных влияют и migrations
являются как Джанго сигналов изменения базы данных. Структура не изменяется, но записи добавляются (как минимум) в две таблицы:
- Новый
ContentType
добавляется django_content_type
для прокси - модели. - Разрешения, специфичные для прокси-модели, добавляются в
auth_permission
. Я предполагаю, что это "всегда" происходит, если прокси не использует одно и то же имя класса. Это, безусловно, происходит - мы на самом деле используем модель прокси для доступа к Пользователю, используя различные разрешения, не затрагивая модель пользователя по умолчанию.
Обе эти детали на самом деле отмечены в цепочке комментариев к проблеме, связанной с OP (например, комментарий # 31), потому что они вносят вклад в ошибку (то есть, что Django ищет разрешения в приложении, отличном от того, которое фактически генерируется в auth_permissions
).