"创建" django基础模型的儿童模型

时间:2016-05-11 23:45:01

标签: python django django-models django-socialauth

我有三个模型,一个名为CommonUser(AbstractUser)的基地和两个孩子,Professional(CommonUser)Client(CommonUser)

我使用django-rest-social-auth来创建来自Facebook,Google等的用户,在我的设置中,我设置AUTH_USER_MODEL = 'users.CommonUser',但我有两个步骤来创建用户,首先使用社交登录,在此之后,我有一个表单来填充来自某类用户的其余数据。

我现在需要从django-rest-social-auth创建的CommonUser创建一个Client或一个Professional实例,换句话说,我想"移动"在提交第二步表单后,由django-rest-social-auth为客户端实例或Professional实例创建的CommonUser实例。

1 个答案:

答案 0 :(得分:2)

经过一些测试和相关搜索,我找到了解决方案。

就我而言,在我保存客户或专业用户的视图中,我将使用:

common_user = CommonUser.objects.get(id=id)
common_user.__class__ = Client
common_user.save()

修改

上述方法看起来不安全第二次this讨论。

更多搜索,我找到了解决方案here

基本上:

class CommonUser(AbstractUser):
    # attributes...

    @classmethod
    def create_child(cls, child_class, attrs):
        """
        Inputs:
        - child_class: child class prototype
        - attrs: dictionary of new attributes for child
        """
        try:
            id = attrs.pop('id', None)
            common_user = CommonUser.objects.get(id=id)
        except Exception as e:
            raise e
        parent_link_field = child_class._meta.parents.get(common_user.__class__, None)
        attrs[parent_link_field.name] = common_user
        for field in common_user._meta.fields:
            value = getattr(common_user, field.name)
            if value:
                attrs[field.name] = value
        s = child_class(**attrs)
        s.save()
        return s


class Professional(CommonUser):
    # attributes...


class Client(CommonUser):
    # attributes...

现在我可以表演:

>>> professional = CommonUser.create_child(Professional, {'id': 1})
>>> client = CommonUser.create_child(Client, {'id': 2})