Django Rest Framework Password Rest Confirm Email未显示表单并返回为none。

huangapple go评论65阅读模式
英文:

Django Rest Framework Password Rest Confirm Email not showing Form and returning as none

问题

在Django Rest Framework中,用户请求重置密码,当收到电子邮件并单击链接时,URL password-reset-confirm/<uidb64>/<token>/ 被请求,但表单未显示,当我将其添加为 {{ form }} 时显示为NONE。

当我在Django上执行所有操作时,密码重置流程完全正常,但如果我尝试从Django Rest Framework中重置密码,表单不会显示。

以下是主要的urls.py:

urlpatterns = [
    path('', include('django.contrib.auth.urls')),
    path('password-reset/', auth_views.PasswordResetView.as_view(template_name='users/password_reset.html', success_url=reverse_lazy('password_reset_done')), name='password_reset'),
    path('password-reset/done/', auth_views.PasswordResetDoneView.as_view(template_name='users/password_reset_done.html'), name='password_reset_done'),
    path('password-reset-confirm/<uidb64>/<token>/', auth_views.PasswordResetConfirmView.as_view(template_name='users/password_reset_confirm.html'), name='password_reset_confirm'),
    path('password-reset-complete/', auth_views.PasswordResetCompleteView.as_view(template_name='users/password_reset_complete.html'), name='password_reset_complete'),
    path('admin/', admin.site.urls),
    path('api/', include('api.urls')),
    path('users/', include('users.urls')),
]

以下是与DRF相关的API app的urls.py:

app_name = 'api'

router = routers.DefaultRouter()
router.register(r'users', UserViewSet, basename='user')

urlpatterns = [
    path('', include(router.urls)),
    path('dj-rest-auth/', include('dj_rest_auth.urls')),
    path('dj-rest-auth/registration/', include('dj_rest_auth.registration.urls')),
    path('token/', TokenObtainPairView.as_view(), name='token_obtain_pair'),
    path('token/refresh/', TokenRefreshView.as_view(), name='token_refresh'),
]

以下是模板password_reset_confirm.html:

<main class="mt-5">
    <div class="container dark-grey-text mt-5">
        <div class="content-section">
            <form method="POST">
                {% csrf_token %}
                <fieldset class="form-group">
                    <legend class="border-bottom mb-4">Reset Password</legend>
                    {{ form|crispy }}
                    {{ form }}
                </fieldset>
                <div class="form-group">
                    <button class="btn btn-outline-info" type="submit">Reset Password</button>
                </div>
            </form>
        </div>
    </div>
</main>

我的问题是:为什么表单显示为NONE,如何修复它。

英文:

In my Django Rest Framework, the users request to reset the password and when the email is received and the link is clicked, the url
password-reset-confirm/&lt;uidb64&gt;/&lt;token&gt;/ as comes up requested but the form is not showing and when I added it as {{ form }} is displayed NONE

The password reset process is working perfectly fine when I do everytihng on the Django but if I try to reset the password from Django
Rest Framework the form does not appear.

Here is the main urls.py

urlpatterns = [
    path(&#39;&#39;, include(&#39;django.contrib.auth.urls&#39;)),
    path(&#39;password-reset/&#39;, auth_views.PasswordResetView.as_view(template_name=&#39;users/password_reset.html&#39;, success_url=reverse_lazy(&#39;password_reset_done&#39;)), name=&#39;password_reset&#39;),
    path(&#39;password-reset/done/&#39;, auth_views.PasswordResetDoneView.as_view(template_name=&#39;users/password_reset_done.html&#39;), name=&#39;password_reset_done&#39;),
    path(&#39;password-reset-confirm/&lt;uidb64&gt;/&lt;token&gt;/&#39;,auth_views.PasswordResetConfirmView.as_view(template_name=&#39;users/password_reset_confirm.html&#39;),name=&#39;password_reset_confirm&#39;,),
    path(&#39;password-reset-complete/&#39;, auth_views.PasswordResetCompleteView.as_view(template_name=&#39;users/password_reset_complete.html&#39;), name=&#39;password_reset_complete&#39;),
    path(&#39;admin/&#39;, admin.site.urls),
    path(&#39;api/&#39;, include(&#39;api.urls&#39;), ),
    path(&#39;users/&#39;, include(&#39;users.urls&#39;), ),
]

Here is the API app urls.py that is related to DRF

app_name = &#39;api&#39;

router = routers.DefaultRouter()
router.register(r&#39;users&#39;, UserViewSet, basename=&#39;user&#39;)

urlpatterns = [
    path(&#39;&#39;, include(router.urls)),
    path(&#39;dj-rest-auth/&#39;, include(&#39;dj_rest_auth.urls&#39;)),
    path(&#39;dj-rest-auth/registration/&#39;, include(&#39;dj_rest_auth.registration.urls&#39;)),
    path(&#39;token/&#39;, TokenObtainPairView.as_view(), name=&#39;token_obtain_pair&#39;),
    path(&#39;token/refresh/&#39;, TokenRefreshView.as_view(), name=&#39;token_refresh&#39;),
]

here is the template password_reset_confirm.html

&lt;main class=&quot;mt-5&quot; &gt;
            &lt;div class=&quot;container dark-grey-text mt-5&quot;&gt;
                &lt;div class=&quot;content-section&quot;&gt;
                    &lt;form method=&quot;POST&quot;&gt;
                        {% csrf_token %}
                        &lt;fieldset class=&quot;form-group&quot;&gt;
                            &lt;legend class=&quot;border-bottom mb-4&quot;&gt;Reset Password&lt;/legend&gt;
                            {{ form|crispy }}
                            {{ form }}

                        &lt;/fieldset&gt;
                        &lt;div class=&quot;form-group&quot;&gt;
                            &lt;button class=&quot;btn btn-outline-info&quot; type=&quot;submit&quot;&gt;Reset Password&lt;/button&gt;
                        &lt;/div&gt;
                    &lt;/form&gt;
                &lt;/div&gt;
            &lt;/div&gt;
        &lt;/main&gt;

My question is: Why is the form showing as NONE and how do I fix it.

答案1

得分: 1

很可能form不会传递到password_reset_confirm.html,因为[Django-rest-framework]默认情况下不会在PasswordResetConfirmView的上下文中包含form

目前,你可以创建一个自定义的PasswordResetConfirmView,继承它并将form传递到模板上下文,使用form_class属性,如下所示:

from django.contrib.auth.forms import SetPasswordForm
from django.contrib.auth.views import PasswordResetConfirmView
from django.utils.decorators import method_decorator
from django.views.decorators.csrf import csrf_protect
from django.views.decorators.debug import sensitive_post_parameters


class CustomPasswordResetConfirmView(PasswordResetConfirmView):
    form_class = SetPasswordForm
    success_url = reverse_lazy('password_reset_complete')
    template_name = 'users/password_reset_confirm.html'

    @method_decorator(sensitive_post_parameters('new_password1', 'new_password2'))
    @method_decorator(csrf_protect)
    def dispatch(self, *args, **kwargs):
        return super().dispatch(*args, **kwargs)

    def get_context_data(self, **kwargs):
        context = super().get_context_data(**kwargs)
        context['form'] = self.form_class(user=self.request.user)
        return context

然后在urls.py中:

urlpatterns = [
    # .......
    path('password-reset-confirm/<uidb64>/<token>/', CustomPasswordResetConfirmView.as_view(), name='password_reset_confirm'),
    # .......
]

根据需要可以提供任何success_url

英文:

Most probably the form is not going to password_reset_confirm.html since [tag:Django-rest-framework] does not include the form in the context of the PasswordResetConfirmView by default.

Currently, the thing you can do is to create a custom PasswordResetConfirmView by inheriting it in a sub class and pass the form to the template context, using form_class attribute so:

from django.contrib.auth.forms import SetPasswordForm
from django.contrib.auth.views import PasswordResetConfirmView
from django.utils.decorators import method_decorator
from django.views.decorators.csrf import csrf_protect
from django.views.decorators.debug import sensitive_post_parameters


class CustomPasswordResetConfirmView(PasswordResetConfirmView):
    form_class = SetPasswordForm
    success_url = reverse_lazy(&#39;password_reset_complete&#39;)
    template_name = &#39;users/password_reset_confirm.html&#39;

    @method_decorator(sensitive_post_parameters(&#39;new_password1&#39;, &#39;new_password2&#39;))
    @method_decorator(csrf_protect)
    def dispatch(self, *args, **kwargs):
        return super().dispatch(*args, **kwargs)

    def get_context_data(self, **kwargs):
        context = super().get_context_data(**kwargs)
        context[&#39;form&#39;] = self.form_class(user=self.request.user)
        return context

Then in urls.py:

urlpatterns = [
    # .......
    path(&#39;password-reset-confirm/&lt;uidb64&gt;/&lt;token&gt;/&#39;, CustomPasswordResetConfirmView.as_view(), name=&#39;password_reset_confirm&#39;),
    # .......
]

You can provide any success_url according to your need.

huangapple
  • 本文由 发表于 2023年2月19日 12:56:57
  • 转载请务必保留本文链接:https://go.coder-hub.com/75498096.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定