我在python 3.6上使用django 1.11。
我能解释问题的最简单方法是在代码中动态创建测试数据库。我使用以下脚本执行此操作:
from uuid import uuid4 as uuid
db = '_' + uuid().hex + 'db.sqlite3'
os.environ.setdefault('DJANGO_TEST_DB_NAME', db)
print(db)
import django
from django.apps import apps
from django.conf import settings
from django.core.management import call_command
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "project.settings")
django.setup()
print("Setting up test database\n")
print("Clearing migrations...\n")
_dir = os.getcwd()
_search = ['project', 'email_auth', 'google', 'app2', 'app3']
for _d in _search:
_walk = os.walk(_dir + os.path.sep + _d)
for _walkObj in _walk:
if _walkObj[0].split(os.path.sep)[-1] == 'migrations' or \
(_walkObj[0].split(os.path.sep)[-2] == 'migrations'
and _walkObj[0].split(os.path.sep)[-1] == '__pycache__'):
for _fName in _walkObj[2]:
os.remove(_walkObj[0] + os.path.sep + _fName)
print("Calling manage:makemigrations\n")
call_command('makemigrations', *_search[1:])
apps.clear_cache()
apps.populate(settings.INSTALLED_APPS)
print("Calling manage:migrate...\n")
call_command('migrate')
print("Creating objects...\n")
call_command('create_objects')
print("Starting server...\n")
call_command('runserver')
无论我对apps对象做了什么(我尝试了一些hacky事情来清除其中的所有内容以重新加载,但没有骰子)或其他任何我无法让django意识到为我的任何一个创建了迁移调用迁移时的应用程序
我甚至尝试过调用migrate,email_auth,并指出django.core.management.base.CommandError: App 'email_auth' does not have migrations.
如果我在makemigrations部分之后取消它,我可以调用此脚本之外的迁移,它可以很好地迁移。
我强烈怀疑它无法正常工作,因为某处django有对模块的旧引用,我不知道如何更新它们。
编辑:
这样就证明它确实在迁移,我上传了一个控制台输出的粘贴框:https://pastebin.com/aSructTW
答案 0 :(得分:0)
我终于想出了如何正确地做到这一点。请注意,要创建/使用测试数据库还有很多,但是这个问题的范围是重新加载应用程序。如果有人想要代码,请告诉我。以下是清除应用程序的功能:
def resetApps(search=[]):
from collections import OrderedDict, defaultdict
import os
import sys
from django.apps import apps
from django.conf import settings
apps.clear_cache()
apps.all_models = defaultdict(OrderedDict)
apps.app_configs = OrderedDict()
apps.stored_app_configs = []
apps.apps_ready = apps.models_ready = apps.ready = False
apps._pending_operations = defaultdict(list)
# clear out py caches of apps as we need to reload
# modify this to allow removal of .pyc files that aren't in pycache, btw
for _d in search:
_walk = os.walk(_dir + os.path.sep + _d)
for _walkObj in _walk:
if _walkObj[0].split(os.path.sep)[-1] == '__pycache__':
for _fName in _walkObj[2]:
os.remove(_walkObj[0] + os.path.sep + _fName)
# clear out sys modules of required things
_toClear = []
for module in sys.modules:
if module.split('.')[0] in search:
_toClear.append(module)
for module in _toClear:
del sys.modules[module]
apps.populate(settings.INSTALLED_APPS)