如何在南迁中访问 auth User 的 User.objects.create_user(...) ?
我没有使用 django 的 auth 模块,而是使用了自己的模块,并且已经非常后悔了。
为了纠正这种情况,我正在尝试将数据从我的用户模型迁移到 django.auth.models.User。
我创建了一个数据迁移,如下所示:
def forwards(self, orm):
"""Migrate user information from mooi User model to auth User model."""
OldUser = orm['mooi.User']
User = orm['auth.User']
Profile = orm['mooi.Profile']
oldUsers = OldUser.objects.all()
for oldUser in oldUsers:
newUser = User.objects.create_user(username=oldUser.id, email=oldUser.email, password=oldUser.password)
# ...more irrelevant code follows...
当我运行迁移时,我收到此错误(回溯):
#...irrelevant traceback precedes...
File "[projdir]/mooi/migrations/0005_from_mooi_users_create_auth_users_with_profiles.py", line 18, in forwards
newUser = User.objects.create_user(username=oldUser.id, email=oldUser.email, password=oldUser.password)
File "[virtual_env_dir]lib/python2.6/site-packages/south/orm.py", line 397, in __getattr__
return getattr(self.real, name)
AttributeError: 'Manager' object has no attribute 'create_user'
经过进一步调查,我发现所引用的 Manager
的时间为 south.orm.NoDryRunManager
解释了错误。
现在,我什至需要 create_user
的原因是创建 django.contrib.auth
能够理解的密码哈希。
说了这么多,我该怎么做呢?考虑到我所处的洞,最优雅的解决方案是什么?
提前致谢。
更新1
按照stevejalim的建议,我尝试使用User
的 set_password(...)
如下:
newUser.set_password(raw_password=oldUser.password)
newUser.save()
但是,由于此错误而失败:
File "[projdir]/mooi/migrations/0005_from_mooi_users_create_auth_users_with_profiles.py", line 21, in forwards
newUser.set_password(raw_password=oldUser.password)
AttributeError: 'User' object has no attribute 'set_password'
我确实在 南方文档 其中指出:
南方并没有冻结一个国家的每一个方面 模型;例如,它没有 保留新的管理器或自定义模型 方法,因为这些需要 序列化运行的Python代码 这些方法(以及代码 取决于,依此类推)。
如果你想在你的 迁移,您必须复制 代码输入,包括任何导入 靠做事。但请记住, 对于您添加的每个导入,您 承诺保持进口有效 为了生命,为了迁徙。
我想问题仍然存在,最好/最安全的方法是什么?复制 set_password(...)
方法?创建一个为我散列密码的函数?还有其他想法吗?
Instead of using django's auth module I've used my own and already regret it a lot.
In an effort to rectify the situation, I'm trying to migrate the data from my User model to django.auth.models.User.
I've created a data migration as follows:
def forwards(self, orm):
"""Migrate user information from mooi User model to auth User model."""
OldUser = orm['mooi.User']
User = orm['auth.User']
Profile = orm['mooi.Profile']
oldUsers = OldUser.objects.all()
for oldUser in oldUsers:
newUser = User.objects.create_user(username=oldUser.id, email=oldUser.email, password=oldUser.password)
# ...more irrelevant code follows...
When I run the migration, I get this error (traceback):
#...irrelevant traceback precedes...
File "[projdir]/mooi/migrations/0005_from_mooi_users_create_auth_users_with_profiles.py", line 18, in forwards
newUser = User.objects.create_user(username=oldUser.id, email=oldUser.email, password=oldUser.password)
File "[virtual_env_dir]lib/python2.6/site-packages/south/orm.py", line 397, in __getattr__
return getattr(self.real, name)
AttributeError: 'Manager' object has no attribute 'create_user'
Upon further investigation, I discovered that the Manager
that was being referred to was of time south.orm.NoDryRunManager
which explains the error.
Now, the reason I even need create_user
is to create a password hash that django.contrib.auth
will understand.
Having said all that, how do I go about doing this? What's the most elegant solution given the hole I'm in?!
Thanks in advance.
Update 1
As suggested by stevejalim, I tried to use User
's set_password(...)
as follows:
newUser.set_password(raw_password=oldUser.password)
newUser.save()
However that failed with this error:
File "[projdir]/mooi/migrations/0005_from_mooi_users_create_auth_users_with_profiles.py", line 21, in forwards
newUser.set_password(raw_password=oldUser.password)
AttributeError: 'User' object has no attribute 'set_password'
I did find a hint in the south documentation which states that:
South doesn’t freeze every aspect of a
model; for example, it doesn’t
preserve new managers, or custom model
methods, as these would require
serialising the python code that runs
those method (and the code that
depends on, and so forth).If you want custom methods in your
migration, you’ll have to copy the
code in, including any imports it
relies on to work. Remember, however,
for every import that you add, you’re
promising to keep that import valid
for the life for the migration.
I guess the question remains, what's the best/safest way of doing this? Copy the set_password(...)
method over? Create a function that hashes the password for me? Any other ideas?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
为什么你不直接导入你需要的东西?
我遇到了同样的问题,我所做的是:
Why you don't just import what you need?.
I had the same problem and what I did was:
好吧,事实证明 South 根本不冻结方法,所以调用任何模型方法都是没有用的。
我解决这个问题的方法是通过处理和修改 contrib.auth 中生成密码的代码。
最终迁移的样子如下:
Ok, it turns out that South doesn't freeze methods at all, so calling any model methods is of no use.
The way I solved this was by coping and modifying the code in contrib.auth that generates passwords.
Here's how the final migration looks like:
在迁移中使用冻结的 ORM 的全部目的是确保新的更改不会干扰旧的实现。 auth 应用程序是 django.contrib 的一部分,我怀疑您正在寻找的功能在过去的几个版本中发生了很大变化,或者计划很快发生变化。除此之外,您不会修改(auth)应用程序或其模型(对吗?对吗?)。因此,可以肯定地说您不需要使用 South 的冻结版本 auth.User;只需正常导入并以这种方式使用即可。
The whole point behind using the frozen ORM in migrations is to ensure that new changes don't interfere with old implementations. The auth app is part of
django.contrib
, and I doubt the functionality you're looking for has changed much in the past few releases, or is planned to change anytime soon. Aside from that, you're not going to be modifying the (auth) app or its models (right? right??). So it's pretty safe to say you don't need to use South's frozen version ofauth.User
; just import it normally and use it that way.为什么不手动创建
User
,然后在使用newUser.set_password()
save()
d后设置密码?是的,您需要敲击数据库两次,但这并不是什么大问题。Why not make the
User
manually, then set the password after it has beensave()
d withnewUser.set_password()
? Yes, you'll need to hit the DB twice, but that's no great shakes.