django 如何成功地将变量传递到python social auth管道?

icomxhvb  于 2023-03-24  发布在  Go
关注(0)|答案(1)|浏览(84)

我正在尝试使用Python Social Auth进行一个非常标准的Django注册过程。在我的例子中,用户:
1.选择他们的计划
1.选择他们的位置
1.创建一个帐户
我想通过Python Social Auth过程传递计划和位置。
我两个都试过了:

SOCIAL_AUTH_FIELDS_STORED_IN_SESSION = ['plan', 'location']
FIELDS_STORED_IN_SESSION = ['plan', 'location']

我两个都试过了:

<form action="{% url "social:complete" "email" %}?plan={{ plan }}&location={{ location }}" method="post" role="form">

以及:

<form action="{% url "social:complete" "email" %}" method="post" role="form">
  <input type="hidden" name="plan" value="{{ plan }}" />
  <input type="hidden" name="location" value="{{ location }}" />

在我的注册用户管道中,我尝试了这两种方法:

plan = strategy.session_get('plan', "trial")

以及:

plan = request.session['plan']

在任何情况下都不会传递变量。计划和位置总是无。我的注册用户在这里:

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',
)

这似乎是一个非常常见的用例,非常困难。

kq0g1dla

kq0g1dla1#

这是最常见的方法...首先在你的Django应用程序中创建一个名为pipeline_user_plan.py的部分管道

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

在您的settings.py

SOCIAL_AUTH_FIELDS_STORED_IN_SESSION = [
    "backend",
    "user_plan",
]
SOCIAL_AUTH_PIPELINE = (
    ...
    "myapp.pipeline_user_plan.require_user_plan_step",
    ...

假设在urls.py中,您有

re_path(
    r"^require-user-plan-view/$",
    views.require_user_plan_view,     
    name="require_user_plan_view",
),

然后在您的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})

这需要一个forms.py

from django import forms

class UserPlanForm(forms.Form):
    user_plan = forms.ChoiceField(widget=forms.RadioSelect)

和模板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>

相关问题