Django模型inheritance:创build现有实例的子实例(downcast)?

我试图整合一个第三方Django的应用程序,使不幸的决定从django.contrib.auth.models.Userinheritance,这是一个可插拔的应用程序的大禁忌。 引用Malcolm Tredinnick :

更重要的是,虽然,就像在Python中一样,用Django的模型inheritance也不能“倒置”。 也就是说,如果你已经创build了User实例,那么你不能在下面探索一下,使得这个实例对应于你尚未创build的子类实例。

那么,我需要将这个第三方应用程序与我现有的用户实例集成在一起。 所以,如果假设我真的愿意在封面上捅一下,我有什么select? 我知道这是行不通的:

 extended_user = ExtendedUser(user_ptr_id=auth_user.pk) extended_user.save() 

有没有例外,但它打破了各种各样的东西,首先用空string覆盖django.contrib.auth.models.User所有列…

这应该工作:

 extended_user = ExtendedUser(user_ptr_id=auth_user.pk) extended_user.__dict__.update(auth_user.__dict__) extended_user.save() 

在这里,你基本上只是将auth_user版本中的值复制到extended_user中,然后重新保存。 不是很优雅,但它的作品。

如果你不喜欢__dict__.update解决scheme,你可以这样做:

 for field in parent_obj._meta.fields setattr(child_obj, field.attname, getattr(parent_obj, field.attname)) 

我通过在django用户邮件列表上询问find了这个答案:

https://groups.google.com/d/msg/django-users/02t83cuEbeg/JnPkriW-omQJ

这不是公共API的一部分,但您可以依靠Django如何在内部加载fixture。

 parent = Restaurant.objects.get(name__iexact="Bob's Place").parent bar = Bar(parent=parent, happy_hour=True) bar.save_base(raw=True) 

请记住,这可能会破坏任何新版本的Django。

我正在使用Django 1.6,而我的ExtendedUser模型来自OSQA( forum.models.user.User )。 由于一些奇怪的原因, dict.__update__setattr的上述解决scheme有时会失败。 这可能与我拥有的其他一些模型有关,即在用户表上施加限制。 以下是另外两种可以尝试的解决方法:

解决方法#1:

 extended_user = ExtendedUser(user_ptr_id = user.pk) extended_user.save() # save first time extended_user.__dict__.update(user.__dict__) extended_user.save() # save second time 

解决方法#2:

 extended_user = ExtendedUser(user_ptr_id = user.pk) extended_user.__dict__.update(user.__dict__) extended_user.id=None extended_user.save() 

也就是说,如果你设置了pkid ,有时候保存新的子实例会失败,但是你可以设置pk ,保存它,然后一切似乎都正常。