python - React : NoReverseMatch: Reverse for 'password_reset_confirm' not found. 'password_reset_confirm' 不是有效的 View 函数或模式名称

标签 python reactjs django django-rest-framework dj-rest-auth

我使用 React 和 Dj-Rest-Auth 进行身份验证。我能够设置登录页面、注册页面和电子邮件确认页面。但是,当我尝试设置密码重置页面时,每次我在重置密码表单中提交电子邮件地址时都会收到此错误:

django          | django.urls.exceptions.NoReverseMatch: Reverse for 'password_reset_confirm' not found. 'password_reset_confirm' is not a valid view function or pattern name.

有谁知道为什么会发生这种情况以及如何解决它?

这就是我的设置方式:

url.py

# API URLS
urlpatterns += [
    # API base url
    path("api/", include("config.api_router")),
    # DRF auth token
    path("auth-token/", obtain_auth_token),
    path('dj-rest-auth/', include('dj_rest_auth.urls')),
    path('dj-rest-auth/registration/', include('dj_rest_auth.registration.urls'))
]

重置.js

import { useState } from 'react';
import { Formik, Field, Form } from 'formik';
import axios from "axios"
import { API } from '../api'

export function Reset() {
    const [loading, setLoading] = useState(false)
    const [success, setSuccess] = useState(false)
    
    function handleSubmit(values, { resetForm }) {
        setLoading(true)
        axios.post(API.auth.passwordReset, values)
            .then(res => {
                resetForm()
                setSuccess(true)
            })
            .finally(() => setLoading(false))
    }

    return (
        <div>
            {success && "You will receive a verification email."}
            {loading && "Loading..."}
            <Formik
                initialValues={{
                    email: '',
                }}
                onSubmit={handleSubmit}>

                {({ errors, touched }) => (
                    <Form>
                        <Field name="email">
                            {({ field, form }) => (
                                <label className="mt-3 block">
                                    <span className="text-gray-700">Email</span>
                                    <input
                                    {...field}
                                    type="text"
                                    className="
                                        mt-1
                                        block
                                        w-full
                                        rounded-md
                                        border-gray-300
                                        shadow-sm
                                        focus:border-indigo-300 focus:ring focus:ring-indigo-200 focus:ring-opacity-50
                                    "
                                    placeholder=""
                                    style={
                                        form.touched.email && form.errors.email ? (
                                            { border: '2px solid var(--primary-red)'}
                                        ) : null
                                    }
                                    />
                                </label>
                            )}
                        </Field>

                       
                        <button className="mt-3 bg-blue-100 rounded-md shadow-sm text-lg px-5 py-3 hover:bg-blue-200" 
                            type="submit">
                            Submit
                        </button>
                    </Form>
                )}

            </Formik>
        </div>
    )

}

App.js

              <Route path="/login" element={<Login />} exact />
              <Route path="/signup" element={<Signup />} exact />
              <Route path="/reset" element={<Reset />} exact />
              <Route path="/accounts/password_reset_confirm" element={<ResetConfirm />} exact />
              <Route path="/accounts/confirm-email/:key" element={<ConfirmEmail />} exact />

API.js

const baseURL = "http://127.0.0.1:8000"
const apiURL = `${baseURL}/api`

export const API = {
    auth: {
        login: `${baseURL}/dj-rest-auth/login/`,
        logout: `${baseURL}/dj-rest-auth/logout/`,
        passwordReset: `${baseURL}/dj-rest-auth/password/reset/`,
        passwordResetConfirm: `${baseURL}/dj-rest-auth/password/reset/confirm/`,
        signup: `${baseURL}/dj-rest-auth/registration/`,
        verifyEmail: `${baseURL}/dj-rest-auth/registration/verify-email/`
    },
    facilities: {
        list: `${apiURL}/facilities/`,
        retrieve: id => `${apiURL}/facilities/${id}/`,
        update: id => `${apiURL}/facilities/${id}/update/`,
    }
}

适配器.py

from typing import Any

from allauth.account.adapter import DefaultAccountAdapter
from allauth.socialaccount.adapter import DefaultSocialAccountAdapter
from django.conf import settings
from django.http import HttpRequest


class AccountAdapter(DefaultAccountAdapter):
    def is_open_for_signup(self, request: HttpRequest):
        return getattr(settings, "ACCOUNT_ALLOW_REGISTRATION", True)

    def send_mail(self, template_prefix, email, context):
        if settings.DEBUG:
            context["activate_url"] = (
                "http://localhost:3000/accounts/confirm-email/" + context["key"]
            )
        else:
            context["activate_url"] = (
                settings.FRONTEND_URL + "/accounts/confirm-email/" + context["key"]
            )
        return super().send_mail(template_prefix, email, context)


class SocialAccountAdapter(DefaultSocialAccountAdapter):
    def is_open_for_signup(self, request: HttpRequest, sociallogin: Any):
        return getattr(settings, "ACCOUNT_ALLOW_REGISTRATION", True)

最佳答案

看到您的 Api.js 文件后,我觉得它看起来不错。我检查了 dj-rest-auth 文档,发现您的问题包含在 FAQ 中(见问题2)。他们建议我们需要添加一个名为 password_reset_confirm 的 url 模式,因此您应该将 urls.py 文件修改为如下内容:

# API URLS
urlpatterns += [
   # sample url pattern from dj-rest-auth demo
   path("password-reset/confirm/<uidb64>/<token>/",
       TemplateView.as_view(template_name="password_reset_confirm.html"),
       name='password_reset_confirm'),
   # API base url
   path("api/", include("config.api_router")),
   # DRF auth token
   path("auth-token/", obtain_auth_token),
   path('dj-rest-auth/', include('dj_rest_auth.urls')),
   path('dj-rest-auth/registration/', include('dj_rest_auth.registration.urls'))
]

我使用了与demo中提供的相同的结构。但使用 path 而不是 url。要查看 password_reset_confirm.html 文件的外观,您可以在演示中检查同一文件 ( https://github.com/iMerica/dj-rest-auth/blob/8a460ecf9a72aec269b75160e5c97f7ed608e247/demo/templates/password_reset_confirm.html )。

此外,您还可以在 django.contrib.auth 中包含 Django 身份验证系统提供的默认 URL(url 可以在 here 中找到,您可以会注意到 L26 中有一个名为 password_reset_confirm 的 url 模式。因此,解决问题的另一种方法是将这些 urls 包含在您的 urls.py 文件中,例如(请参阅 https://docs.djangoproject.com/en/4.0/topics/auth/default/#using-the-views-1 ):

# API URLS
urlpatterns += [
   # include urls from django.contrib.auth
   path('dj-auth/', include('django.contrib.auth.urls')),
   # API base url
   path("api/", include("config.api_router")),
   # DRF auth token
   path("auth-token/", obtain_auth_token),
   path('dj-rest-auth/', include('dj_rest_auth.urls')),
   path('dj-rest-auth/registration/', include('dj_rest_auth.registration.urls'))
]

关于python - React : NoReverseMatch: Reverse for 'password_reset_confirm' not found. 'password_reset_confirm' 不是有效的 View 函数或模式名称,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/72099416/

相关文章:

python - 如何将覆盖率结果与 tox 结合起来?

python - 如何使用 python 从 gs 存储桶中获取文件数

python - Django 和 web.py,用 Python 建大型网站哪个更好?

Django 和 Linux,端口转发

django - 两个模型可以通过ForeignKey互相引用吗?

python - 如何向下滚动网页直到单击特定按钮?

python - 将 pd.get_dummies 结果转换为 df.str.get_dummies

javascript - 使用React、redux和react-redux-router进行登录验证: the proper way?

javascript - Antd:如何获取特定单元格点击中的整行值?

html - 如何在 React 中构建高级过滤器组件?