Search code examples
pythondjangodjango-modelspython-social-authdjango-socialauth

Extend User Model or Custom Pipeline in Social-App-Django


I am implementing social-app-django (not the deprecated one; the one that relies on Python-social-auth) with django 1.11 (not using Mongo). My application will need to store and manipulate a lot of data on users other than that which is fetched from their social media accounts at login.

I don't need to fetch or collect any extra data when the user authenticates, but various actions they perform on my site will need to be saved to their user model. I am wondering which of the following approaches is preferred (I've searched extensively online, but can't find a specific explanation of why to use one vs the other):

  • Create my own user model in my app's models.py (call it MyUser) that doesn't extend anything special, and then add a function in the authentication pipeline that associates the social-app-django user with a corresponding instance of MyUser. Leave AUTH_USER_MODEL and SOCIAL_AUTH_USER_MODEL unchanged.

    or...

  • Create my own user model in my app's models.py, and in the project's settings.py set AUTH_USER_MODEL and SOCIAL_AUTH_USER_MODEL to point to MyUser. Leave the pipeline unchanged. In this case, I was wondering whether someone could clarify what MyUser and its manager should extend, and what I need to import in modules.py (I am confused because a lot of stack overflow posts are referring to deprecated versions of this module and I keep getting errors). Also, in this case should I be setting both AUTH_USER_MODEL and SOCIAL_AUTH_USER_MODEL, or just one of them?

Do these two methods essentially achieve the same thing? Is one more reliable/preferred for some reason? Or, should I be doing both? Thanks very much for any assistance.

Another detail: I would like to be able to access the User database not only from the app I am currently building, but also from other apps (within the same Django project) that I will build in the future. Does this affect anything?


Solution

  • Since I see this has a decent number of views I will post the solution I eventually came to.

    Both django and social-app-django (or any other social auth module) make use of the default User model for authentication. While it's possible to edit this model to add custom parameters, I don't recommend it. It's not good abstraction or modularization. If you make a mistake when configuring the model, you won't just break a specific feature on your site, but you might also break the authentication itself.

    The only circumstances I can think of under which you'd want to edit the default user model itself is if you need to make changes that affect the authentication flow itself (for example, adding your own custom authentication provider).

    It's much easier and safer to create a new model called UserProfile, with a required one-to-one relationship to a User object. Now, you can treat the User object as the authentication part, and the UserProfile object as the content/storage part. You won't have to mess with the User model very often, and the UserProfile model doesn't matter for authentication purposes. Note that in this configuration you should NOT need to change the AUTH_USER_MODEL or SOCIAL_AUTH_USER_MODEL fields in the settings.py file.

    If you take this approach, you will need to add a custom step in the authentication pipeline in which you create a new UserProfile object and associate it with the User who is currently logging in.