Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/295.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/django/23.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python Django模型继承:创建现有实例的子实例(向下转换)?_Python_Django_Inheritance - Fatal编程技术网

Python Django模型继承:创建现有实例的子实例(向下转换)?

Python Django模型继承:创建现有实例的子实例(向下转换)?,python,django,inheritance,Python,Django,Inheritance,我正在尝试集成一个第三方Django应用程序,该应用程序做出了从Django.contrib.auth.models.User继承的不幸决定,这对于可插拔应用程序来说是一个很大的禁忌。引述: 不过,更重要的是,正如在Python中一样,您不能使用 Django的模型继承。也就是说,如果您已经创建了用户 比如说,如果你不在被子底下翻来覆去的话,你就无法做到这一点 实例对应于尚未创建的子类实例 嗯,我现在的情况是,我需要将这个第三方应用程序与我现有的用户实例集成。那么,如果假设我真的愿意在被子底下翻

我正在尝试集成一个第三方Django应用程序,该应用程序做出了从
Django.contrib.auth.models.User
继承的不幸决定,这对于可插拔应用程序来说是一个很大的禁忌。引述:

不过,更重要的是,正如在Python中一样,您不能使用 Django的模型继承。也就是说,如果您已经创建了用户 比如说,如果你不在被子底下翻来覆去的话,你就无法做到这一点 实例对应于尚未创建的子类实例

嗯,我现在的情况是,我需要将这个第三方应用程序与我现有的用户实例集成。那么,如果假设我真的愿意在被子底下翻来覆去,我有什么选择呢?我知道这是行不通的:

extended_user = ExtendedUser(user_ptr_id=auth_user.pk)
extended_user.save()
没有例外,但它会破坏所有类型的内容,首先用空字符串覆盖
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_用户版本中的值复制到extended_用户版本中,然后重新保存它。不是很优雅,但它可以工作。

如果您不喜欢
\uu dict\uuuuu。更新解决方案,您可以执行以下操作:

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

我使用的是Django 1.6,我的
ExtendedUser
模型来自OSQA(
forum.models.user.user
)。出于某种奇怪的原因,上述使用
指令的解决方案和使用
setattr
的解决方案有时会失败。这可能与我拥有的其他一些模型有关,这些模型在用户表上设置了约束。您还可以尝试以下两种变通方法:

解决办法#1:

解决办法#2:


也就是说,如果同时设置
pk
id
,有时保存新的子实例会失败,但您可以只设置
pk
,保存它,然后一切似乎都正常工作。

我通过询问django用户邮件列表找到了这个答案:

这不是公共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的任何新版本决裂。

这样的东西怎么样:

from django.forms.models import model_to_dict

auth_user_dict = model_to_dict(auth_user)
extended_user = ExtendedUser.objects.create(user_ptr=auth_user, **auth_user_dict)

对于这个问题,有一个公开的bug:

建议的修补程序()未使用
obj.\uuu dict\uuu
但是创建一个字典,其中所有字段值在所有字段上循环。 这里有一个简化的函数:

def create_child_from_parent_model(child_cls, parent_obj, init_values: dict):
    attrs = {}
    for field in parent_obj._meta._get_fields(reverse=False, include_parents=True):
        if field.attname not in attrs:
            attrs[field.attname] = getattr(parent_obj, field.attname)
    attrs[child_cls._meta.parents[parent_obj.__class__].name] = parent_obj
    attrs.update(init_values)
    print(attrs)
    return child_cls(**attrs)

create_child_from_parent_model(ExtendedUser, auth_user, {})
此方法的优点是,被子方法覆盖的方法不会被原始父方法替换。
对于我来说,使用原始答案
obj.\uu dict\uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu

parent_object = parent_model.objects.get(pk=parent_id)  
new_child_object_with_existing_parent = Child(parent_ptr=parent, child_filed1='Nothing')
new_child_object_with_existing_parent.save()
我想在我的个人资料模型中为现有用户创建条目,我的模型如下

from django.contrib.auth.models import User as user_model
class Profile(user_model):
     bio = models.CharField(maxlength=1000)
     another_filed = models.CharField(maxlength=1000, null=True, blank=True)
在某个地方,如果现有用户不存在配置文件,我需要创建配置文件,所以我像下面这样做

对我有用的例子

from meetings.user import Profile
from django.contrib.auth.models import User as user_model

user_object = user_model.objects.get(pk=3)  
profile_object = Profile(user_ptr=user_object, bio='some')
profile_object.save()

太好了,谢谢你,丹尼尔。让我摆脱了这个困境:。在保存之前,您应该从dict中排除pk或将其重置为无。另见另一个答案。否则你只是在等待一个完整的错误。男人终于解决了。在这个问题上耽搁太久了。谢谢有人知道如何在不重新保存/更新所有字段的情况下执行此操作吗??我试图在保存中指定select update_字段,但无法确定需要什么。我尝试过(pk、id、user_ptr_id和parent)和一些更牵强的方法,但都不管用!这给了我一个错误“无法设置属性”当通过管理操作使用时。这似乎适用于除许多字段之外的所有字段,不幸的是这对我来说是一个问题。如果是这样的话,你知道怎么办吗?
from django.contrib.auth.models import User as user_model
class Profile(user_model):
     bio = models.CharField(maxlength=1000)
     another_filed = models.CharField(maxlength=1000, null=True, blank=True)
from meetings.user import Profile
from django.contrib.auth.models import User as user_model

user_object = user_model.objects.get(pk=3)  
profile_object = Profile(user_ptr=user_object, bio='some')
profile_object.save()