Reputation: 5005
I'm trying to do a pretty standard Django sign up process with Python Social Auth. In my case the user:
I want to pass the the plan and location through the Python Social Auth process.
I've tried both:
SOCIAL_AUTH_FIELDS_STORED_IN_SESSION = ['plan', 'location']
FIELDS_STORED_IN_SESSION = ['plan', 'location']
I've tried both:
<form action="{% url "social:complete" "email" %}?plan={{ plan }}&location={{ location }}" method="post" role="form">
and:
<form action="{% url "social:complete" "email" %}" method="post" role="form">
<input type="hidden" name="plan" value="{{ plan }}" />
<input type="hidden" name="location" value="{{ location }}" />
In my register user pipeline, I've tried both:
plan = strategy.session_get('plan', "trial")
and:
plan = request.session['plan']
In no case is the variable passed through. Plan and location are always none. My register user is here:
SOCIAL_AUTH_PIPELINE = (
#'social.pipeline.debug.debug',
'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',
'myproject.pipelines.register_user',
'social.pipeline.social_auth.associate_by_email',
'social.pipeline.social_auth.associate_user',
'social.pipeline.social_auth.load_extra_data',
'social.pipeline.user.user_details',
)
This seems a REALLY common use case to be so difficult.
Upvotes: 4
Views: 1126
Reputation: 15622
Here's the most common approach... start by creating a partial pipeline named pipeline_user_plan.py
in one of your Django apps
from django.shortcuts import redirect
from social_core.pipeline.partial import partial
@partial
def require_user_plan_step(
strategy, backend, details, request, *args, is_new=False, **kwargs
):
user_plan = strategy.session_get("user_plan", None)
if is_new and not user_plan:
request.session["backend"] = backend.name
return redirect("require_user_plan_view")
return None
In your settings.py
SOCIAL_AUTH_FIELDS_STORED_IN_SESSION = [
"backend",
"user_plan",
]
SOCIAL_AUTH_PIPELINE = (
...
"myapp.pipeline_user_plan.require_user_plan_step",
...
That assumes in your urls.py
you have
re_path(
r"^require-user-plan-view/$",
views.require_user_plan_view,
name="require_user_plan_view",
),
Then in your views.py
def require_user_plan_view(request):
if request.method == "POST":
request.session["user_plan"] = request.POST["user_plan"]
backend_name = request.session["backend"]
return redirect(reverse("social:complete", args=(backend_name,)))
form = UserPlanForm()
return render(request, "require-user-plan-form.html", {"form": form})
which require a forms.py
like
from django import forms
class UserPlanForm(forms.Form):
user_plan = forms.ChoiceField(widget=forms.RadioSelect)
and a template require-user-plan-form.html
<form method="post">
{% csrf_token %}
{{ form.as_p }}
<input type="submit" class="btn btn-neutral" id="submit" value="Submit" />
</form>
Upvotes: 0