Django: ContentTypes во время миграции при выполнении тестов

Я перенес а ForeignKey в GenericForeignKey, используя структуру contrib.contenttypes. Чтобы получить доступ к объекту ContentType, мне нужно перенести данные, я использовал этот код:

ContentType = apps.get_model('contenttypes', 'ContentType')

my_model_content_type = ContentType.objects.get(
    app_label='my_app',
    model='my_model'
)

Миграция работает, когда я запускаю manage.py migrate, и я могу без проблем играть с обновленной моделью в оболочке.

Однако, когда я пытаюсь запустить manage.py test, я получаю следующую ошибку в строке ContentTypes.object.get():

__fake__.DoesNotExist: ContentType matching query does not exist.

Запрос для ContentType.objects.all() в это время возвращает пустой запрос.

Я попытался (как было сказано другим ответом здесь в SO) запустить это перед моим запросом, но безрезультатно:

update_contenttypes(apps.app_configs['contenttypes'])
update_contenttypes(apps.app_configs['my_app'])

Как я могу гарантировать, что строки ContentType существуют в этой точке миграции тестовой базы данных?

Ответ 1

Это то, что в конечном итоге работает для меня. Во-первых, импортируйте update_contenttypes:

from django.contrib.contenttypes.management import update_contenttypes

Во-вторых, укажите начальную миграцию ContentType как зависимость:

dependencies = [
    ('contenttypes', '0001_initial'),
    ...
]

Наконец, в функции миграции forward (вызывается через RunPython в миграции operations):

# Ensure ContentType objects exist at this point:
app_config = apps.get_app_config('my_app')
app_config.models_module = app_config.models_module or True

update_contenttypes(app_config)

Вам может потребоваться выполнить вышеуказанный код более чем на один app_config. Вы можете получить все объекты app_config с помощью apps.get_app_configs() и итерации.