0

I have three models, a base called CommonUser(AbstractUser) and two children, Professional(CommonUser) and Client(CommonUser).

I'm using the django-rest-social-auth to create users from Facebook, Google, etc., and in my settings, I set AUTH_USER_MODEL = 'users.CommonUser', but I have two steps to create users, first using the social login, after this, I have a form to fill rest of data from a type of user.

I need now to create a Client or a Professional instance from the CommonUser created by the django-rest-social-auth, in other words, I want to "move" the CommonUser instance created by django-rest-social-auth to a Client instance or a Professional instance after submit the second step form.

1 Answers1

3

After some tests and related searchs I found a solution.

In my case, in the view where I'll save the Client or Professional user, I'll use:

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

EDIT

The method above looks insecure second this discussion.

Some more searches and I found the solution here

Basically:

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...

And now I can perform:

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