首页 > 解决方案 > Django NoReverseMatch URL 重定向

问题描述

我正在尝试使用 django 3 中的 allauth 自定义注册重定向 url。我收到了这个错误,而不是:

NoReverseMatch at /accounts/candidate-signup/

Reverse for 'candidate_profile' with no arguments not found. 1 pattern(s) tried: ['accounts/profile/(?P<username>[^/]+)/$']

视图.py

from django.shortcuts import render
from django.views import View

from .models import CandidateProfile
from .forms import CandidateProfileForm

from allauth.account import app_settings
from allauth.account.views import SignupView
from allauth.account.utils import complete_signup
from allauth.exceptions import ImmediateHttpResponse


class CandidateSignUpView(SignupView, View):
    def get(self, request, *args, **kwargs):
        form = self.form_class(request.POST)
        return render(request, self.template_name, {'form': form})

    def form_valid(self, form):
        self.user = form.save(self.request)
        self.user.is_candidate = True
        self.user.save()
        success_url = f'profile/{self.user.username}/'
        try:
            return complete_signup(
                self.request,
                self.user,
                app_settings.EMAIL_VERIFICATION,
                self.success_url,
            )
        except ImmediateHttpResponse as e:
            return e.response

网址.py

from django.urls import path

from . import views

urlpatterns = [
    path('candidate-signup/', views.CandidateSignUpView.as_view(), name='candidate_signup'),
    path('company-signup/', views.CompanySignUpView.as_view(), name='company_signup'),
    path('profile/<str:username>/', views.CandidateProfileView.as_view(), name='candidate_profile'),
]

django/conf/global_settings.py

LOGIN_REDIRECT_URL = 'candidate_profile'

html

                <form class="signup" id="signup_form" method="post" action="{% url 'candidate_signup' %}">
                    {% csrf_token %}
                    {{ form.as_p }}
                    {% if redirect_field_value %}
                        <input type="hidden" name="{{ redirect_field_name }}" value="{{ redirect_field_value }}" />
                    {% endif %}

一个可行的解决方案将从注册页面重定向到/accounts/profile/<str:username>/

标签: pythonhtmldjango

解决方案


你有两个问题CandidateSignUpView

  1. 您传递self.success_urlcomplete_signup,而不是传递,这是在方法中success_url本地定义的。form_valid按原样self.success_urlNoneSignupView在您的 中定义并继承CandidateSignUpView),complete_signup正在接收Noneforsuccess_url参数,因此它success_url在登录后使用默认值。
  2. 您最好不要手动构建 url。为此,您最好使用reverse并传递视图名称和相应的参数,因此success_url = f'profile/{self.user.username}/'您最好使用success_url = reverse('candidate_profile',kwargs={'username':self.user.username}). reverse 在这里查看更多信息。

所以,你CandidateSignUpView应该是这样的:

from django.shortcuts import render
from django.views import View

from .models import CandidateProfile
from .forms import CandidateProfileForm

from allauth.account.views import SignupView
from allauth.account.utils import complete_signup
from allauth.exceptions import ImmediateHttpResponse
from django.http.response import HttpResponse
from django.urls.base import reverse


class CandidateSignUpView(SignupView, View):
    def get(self, request, *args, **kwargs):
        form = self.form_class(request.POST)
        return render(request, self.template_name, {'form': form})

    def form_valid(self, form):
        self.user = form.save(self.request)
        self.user.is_candidate = True
        self.user.save()
        # success_url = f'profile/{self.user.username}/'
        success_url = reverse('candidate_profile',kwargs={'username':self.user.username})
        
        try:
            return complete_signup(
                self.request,
                self.user,
                app_settings.EMAIL_VERIFICATION,
                # self.success_url,
                success_url
            )
        except ImmediateHttpResponse as e:
            return e.response

推荐阅读