pythondjangosteampython-social-auth

Custom user model with python-social-auth on django


I am new to this so sorry if what I am asking sounds silly. I am using only steamopenid on python-social-auth for the login, that's the only option the customer will have. Now I want to create my own custom user model where I can keep the user data once they log in. I believe it should not be too complicated but I can't find anything that seems correct.

I have managed to get username but I want to also get everything that's under user social auths table and users table. The fields that are saved into python-social-auth generated table: Database

settings.py

SOCIAL_AUTH_PIPELINE = (
    'social_core.pipeline.social_auth.social_details',
    'social_core.pipeline.social_auth.social_uid',
    'social_core.pipeline.social_auth.social_user',
    'social_core.pipeline.user.get_username',
    'social_core.pipeline.social_auth.associate_by_email',
    'social_core.pipeline.user.create_user',
    'social_core.pipeline.social_auth.associate_user',
    'social_core.pipeline.social_auth.load_extra_data',
    'social_core.pipeline.user.user_details',
    'main.pipeline.save_profile',
)

pipeline.py

from .models import CustomUser


def save_profile(backend, user, response, *args, **kwargs):
    CustomUser.objects.create(
        user = user,
    )

models.py

from django.db import models
from django.conf import settings

# Create your models here.

class CustomUser(models.Model):
    user = models.OneToOneField(settings.AUTH_USER_MODEL, on_delete=models.CASCADE)

New models.py

from django.db import models
from django.conf import settings

from django.contrib.auth.models import AbstractUser




# Create your models here.

class CustomUser(AbstractUser):
    username = models.CharField(max_length=200, null=True)

    name = models.CharField(max_length=200, unique=True)

    steam_name = models.CharField(max_length=32, blank=True)
    steam_id = models.CharField(max_length=17, unique=True, blank=True, null=True)
    extra_data = models.TextField(null=True)

    is_active = models.BooleanField(default=True, db_column='status')
    is_staff = models.BooleanField(default=False, db_column='isstaff')
    is_superuser = models.BooleanField(default=False, db_column='issuperuser')

    USERNAME_FIELD = "name"
    REQUIRED_FIELDS = ["username"]

Solution

  • You created a model which has a reference to the default user model of django. But I think that you want is customize your own model user. The option that i prefer is code a new model that inherits from AbstractBaseUser, which just have a few fields and you be able to add your own needed fields (if you want to use the admin site make sure of append is_staff, is_superuser and to make better control override is_active).

    The last step is change in settings.py to use this model as your user model. I

    from app.models impor NameModelUser
    AUTH_USER_MODEL = 'app.NameModelUser'
    

    For more of this, check the documentation: Specifying a custom user model

    Now to catch the data of steam, that I have done is create a function to use in my pipeline of PSA. Basically you only have to put the correct parameters and get the data of them. Example:

    def save_buyer(backend, response, details, user, *args, **kwargs) -> Dict[str, any]:
        """
        Parameters
        ----------
        backend: Union[GoogleOpenIdConnect, FacebookOAuth2, TwitterOAuth]
            Instance of the provider used to the authentication.
        response: Dict[str, str]
            The response of the Oauth request in json format.
        details: Dict[str, str]
            The response with user details in provider.
        user: Usuario
            Instance of the user (already registered).
        kwargs: Dict[str, bool]
            Distinct data about the execution of the pipeline.
        """
        last_name = details['last_name'] if details['last_name'] != '' else None
        if backend.name == 'facebook':
            MyUserModel(
                email=user,
                name=details['first_name'],
                last_name=last_name
            ).save()
    

    So the key are details, user and even the response (for other data). See more in Extending the Pipeline.