Question

I have Facebook authentication working on my site, but I need the user to fill a profile form during his authentication. I have used an authentication pipeline to do so but whithout success. The pipeline is being called like it should, but the result is an error.

Let's say I need his mobile number - consider it does not come from Facebook.

Please consider:

models.py

from django.db import models
from django.contrib.auth.models import User

class Profile(models.Model):
    user = models.OneToOneField(User)
    mobile = models.IntegerField()

settings.py

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.mail.mail_validation',
    'social.pipeline.user.create_user',
    'social.pipeline.social_auth.associate_user',
    'social.pipeline.social_auth.load_extra_data',
    'social.pipeline.user.user_details',
    'myapp.pipeline.fill_profile',
)

pipeline.py

from myapp.models import Profile
from social.pipeline.partial import partial

@partial
def fill_profile(strategy, details, user=None, is_new=False, *args, **kwargs):
    try:
        if user and user.profile:
            return
        except:
            return redirect('myapp.views.profile')

myapp/views.py

from django.shortcuts import render, redirect 
from myapp.models import Perfil

def profile(request):
    if request.method == 'POST':
        profile = Perfil(user=request.user,mobile=request.POST.get('mobile'))           
        profile.save()
        backend = request.session['partial_pipeline']['backend']
        redirect('social:complete', backend=)
    return render(request,'profile.html')

The profile.html is just a form with an input text box named 'mobile' and a submit button.

Then I get this error:

Cannot assign "<SimpleLazyObject: <django.contrib.auth.models.AnonymousUser object at 0x03C2FB10>>": "Profile.user" must be a "User" instance.

Why can't I access the User instance since the user in auth_user table is already there (I suppose)?

Please, what's wrong with this?

Was it helpful?

Solution

You can't access the user in request.user because it's not logged in yet, the user will be logged in social complete view after the pipeline executed. Usually partial pipeline views will save the form data into the session and then the pipeline will pick it and save it. Also you can set the user id in the session in your pipeline and then pick that value in your view. For example:

@partial
def fill_profile(strategy, user, *args, **kwargs):
    ...
    strategy.session_set('user_id', user.id)
    return redirect(...)
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top