Reputation: 11833
I'm using python-social-auth
(not django-social-auth because it's depreciated) for authentication in Django REST backend applciation with Custom User Model
described below.
from django.contrib.auth.models import AbstractBaseUser, UserManager
class User(AbstractBaseUser):
class Gender():
MALE = 0
FEMALE = 1
UNKNOWN = 2
CHOICES = [(MALE, 'Male'), (FEMALE, 'Female'), (UNKNOWN, 'Unknown')]
username = models.CharField(_('username'), max_length=30, unique=True,
help_text=_('Required. 30 characters or fewer. Letters, digits and '
'@/./+/-/_ only.'),
validators=[
validators.RegexValidator(r'^[\w.@+-]+$', _('Enter a valid username.'), 'invalid')
])
first_name = models.CharField(max_length=30, blank=True)
last_name = models.CharField(max_length=30, blank=True)
email = models.EmailField(blank=True)
is_staff = models.BooleanField(default=False)
is_active = models.BooleanField(_('active'), default=True)
date_joined = models.DateTimeField(default=timezone.now)
gender = models.IntegerField(choices=Gender.CHOICES, default=Gender.UNKNOWN)
birthday = models.DateField(default=timezone.now)
facebook_id = models.CharField(max_length=30, blank=True)
USERNAME_FIELD = 'username'
REQUIRED_FIELDS = ['email']
objects = UserManager()
def __unicode__(self):
return self.username
def save(self, *args, **kwargs):
""" ensure instance has usable password when created """
if not self.pk and self.has_usable_password() is False:
self.set_password(self.password)
super(User, self).save(*args, **kwargs)
Notice that I don't implement a custom UserManager
. Social auth pipline is also straightforward.
AUTHENTICATION_BACKENDS = (
'social.backends.facebook.FacebookOAuth2',
'django.contrib.auth.backends.ModelBackend',
)
SOCIAL_AUTH_PIPELINE = (
'social.pipeline.social_auth.social_details',
'social.pipeline.social_auth.social_uid',
'social.pipeline.social_auth.auth_allowed',
'social.pipeline.social_auth.social_user',
'social.pipeline.user.get_username',
'social.pipeline.social_auth.associate_by_email',
'social.pipeline.user.create_user',
'social.pipeline.social_auth.associate_user',
'social.pipeline.social_auth.load_extra_data',
'social.pipeline.user.user_details'
)
However, when I try to authenticate with Facebook, it gives an error as below
TypeError at /api-token/login/facebook/
'is_superuser' is an invalid keyword argument for this function
The problem is, probably, python-social-auth
try to use django's own User instead of custom User Model that I defined.
In django-social-auth
there is a setting's parameter like SOCIAL_AUTH_USER_MODEL
but I couldn't find any way to do it in python-social-auth
How can I make it possible to use my custom user model in python-social-auth?
Upvotes: 1
Views: 5884
Reputation: 11833
There has to be a Custom UserManager as well described below. I removed is_superuser=is_superuser
field while creating new user.
class UserManager(BaseUserManager):
def _create_user(self, username, email, password,
is_staff, is_superuser, **extra_fields):
"""
Creates and saves a User with the given username, email and password.
"""
now = timezone.now()
if not username:
raise ValueError('The given username must be set')
email = self.normalize_email(email)
user = self.model(username=username, email=email,
is_staff=is_staff, is_active=True, last_login=now,
date_joined=now, **extra_fields)
user.set_password(password)
user.save(using=self._db)
return user
def create_user(self, username, email=None, password=None, **extra_fields):
return self._create_user(username, email, password, False, False,
**extra_fields)
def create_superuser(self, username, email, password, **extra_fields):
return self._create_user(username, email, password, True, True,
**extra_fields)
Upvotes: 0