25π
The pre_social_login
signal is sent after a user successfully
authenticates via a social provider, but before the login is actually
processed. This signal is emitted for social logins, signups and when
connecting additional social accounts to an account.
So it is sent before the signup is fully completed β therefore this not the proper signal to use.
Instead, I recommend you use allauth.account.signals.user_signed_up
, which is emitted for all users, local and social ones.
From within that handler you can inspect whatever SocialAccount
is attached to the user. For example, if you want to inspect Google+ specific data, do this:
user.socialaccount_set.filter(provider='google')[0].extra_data
UPDATE: the latest development version makes this a little bit more convenient by passing along a sociallogin
parameter that directly contains all related info (social account, token, β¦)
11π
Here is a Concrete example of @pennersr solution :
Assumming your profile model has these 3 fields: first_name
, email
, picture_url
views.py:
@receiver(user_signed_up)
def populate_profile(sociallogin, user, **kwargs):
if sociallogin.account.provider == 'facebook':
user_data = user.socialaccount_set.filter(provider='facebook')[0].extra_data
picture_url = "http://graph.facebook.com/" + sociallogin.account.uid + "/picture?type=large"
email = user_data['email']
first_name = user_data['first_name']
if sociallogin.account.provider == 'linkedin':
user_data = user.socialaccount_set.filter(provider='linkedin')[0].extra_data
picture_url = user_data['picture-urls']['picture-url']
email = user_data['email-address']
first_name = user_data['first-name']
if sociallogin.account.provider == 'twitter':
user_data = user.socialaccount_set.filter(provider='twitter')[0].extra_data
picture_url = user_data['profile_image_url']
picture_url = picture_url.rsplit("_", 1)[0] + "." + picture_url.rsplit(".", 1)[1]
email = user_data['email']
first_name = user_data['name'].split()[0]
user.profile.avatar_url = picture_url
user.profile.email_address = email
user.profile.first_name = first_name
user.profile.save()
If you are confused about those picture_url
variable in each provider. Then take a look at the docs:
facebook:
picture_url = "http://graph.facebook.com/" + sociallogin.account.uid + "/picture?type=large"
Docs
linkedin:
picture_url = user_data['picture-urls']['picture-url']
Docs
twitter:
picture_url = picture_url.rsplit("_", 1)[0] + "." + picture_url.rsplit(".", 1)[1]
Docs And for the rsplit()
take a look here
Hope that helps. π
- Django: WSGIRequest' object has no attribute 'user' on some pages?
- Could not import 'oauth2_provider.ext.rest_framework.OAuth2Authentication' for API setting 'DEFAULT_AUTHENTICATION_CLASSES'
- How does django-nose differ from the default Django test-runner
- Django-Rest-Framework serializer class meta
2π
I am doing in this way and taking picture (field) url and google provider(field) as an example.
socialaccount_obj = SocialAccount.objects.filter(provider='google', user_id=self.user.id)
picture = "not available"
if len(socialaccount_obj):
picture = socialaccount_obj[0].extra_data['picture']
make sure to import : from allauth.socialaccount.models import SocialAccount
1π
There is an easier way to do this.
Just add the following to your settings.py. For example, Linked inβ¦
SOCIALACCOUNT_PROVIDERS = {
'linkedin': {
'SCOPE': [
'r_basicprofile',
'r_emailaddress'
],
'PROFILE_FIELDS': [
'id',
'first-name',
'last-name',
'email-address',
'picture-url',
'public-profile-url',
]
}
The fields are automatically pulled across.
- You cannot add messages without installing django.contrib.messages.middleware.MessageMiddleware
- Django ALLOWED_HOSTS with ELB HealthCheck
- How to make Django Password Reset Email Beautiful HTML?