我厌倦了与 South 的斗争,所以实际上我最终以不同的方式做这件事,并且对于我的特殊情况来说效果很好:
首先,我使用 ./manage.py 转储数据,修复转储,然后使用 ./manage.py 加载数据,它有效。然后我意识到我可以用一个独立的脚本来做基本相同的事情,它只加载必要的 django 设置并直接进行序列化/反序列化。
自包含的python脚本
## userconverter.py ##
import json
from django.conf import settings
settings.configure(
DATABASES={
# copy DATABASES configuration from your settings file here, or import it directly from your settings file (but not from django.conf.settings) or use dj_database_url
},
SITE_ID = 1, # because my custom user implicates contrib.sites (which is why it's in INSTALLED_APPS too)
INSTALLED_APPS = ['django.contrib.sites', 'django.contrib.auth', 'myapp'])
# some things you have to import after you configure the settings
from django.core import serializers
from django.contrib.auth.models import User
# this isn't optimized for huge amounts of data -- use streaming techniques rather than loads/dumps if that is your case
old_users = json.loads(serializers.serialize('json', User.objects.all()))
for user in old_users:
user['pk'] = None
user['model'] = "myapp.siteuser"
user['fields']["site"] = settings['SITE_ID']
for new_user in serializers.deserialize('json', json.dumps(old_users)):
new_user.save()
使用转储数据/加载数据
我做了以下事情:
1) ./manage.py 转储数据 auth.User
2) 将 auth.user 数据转换为新用户的脚本。(或者只是在你最喜欢的文本编辑器或 grep 中手动搜索和替换)我的看起来像:
def convert_user_dump(filename, site_id):
file = open(filename, 'r')
contents = file.read()
file.close()
user_list = json.loads(contents)
for user in user_list:
user['pk'] = None # it will auto-increment
user['model'] = "myapp.siteuser"
user['fields']["site"] = side_id
contents = json.dumps(user_list)
file = open(filename, 'w')
file.write(contents)
file.close()
3) ./manage.py 加载数据文件名
4) 设置 AUTH_USER_MODEL
*旁注:无论您使用哪种技术(South、序列化/修改/反序列化或其他),进行此类迁移的一个关键部分是,只要您在当前设置中将 AUTH_USER_MODEL 设置为自定义模型,django将您与 auth.User 断开连接,即使该表仍然存在。*