对普通django视图进行子类化



我想在django附带的LoginView中添加一行。我知道如何通过子类化来实现这一点,但我有一种感觉,我不需要复制我想要子类化的视图中的所有代码。

我添加的唯一一行是此视图中的倒数第二行。该视图中的其余代码100%与django-vanilla LoginView相同。

对这个视图进行子类化并添加这一行代码最有效的方法是什么?

class CustomLoginView(LoginView):
"""
Display the login form and handle the login action.
"""
form_class = AuthenticationForm
authentication_form = None
redirect_field_name = REDIRECT_FIELD_NAME
template_name = 'registration/login.html'
redirect_authenticated_user = False
extra_context = None
@method_decorator(sensitive_post_parameters())
@method_decorator(csrf_protect)
@method_decorator(never_cache)
def dispatch(self, request, *args, **kwargs):
if self.redirect_authenticated_user and self.request.user.is_authenticated:
redirect_to = self.get_success_url()
if redirect_to == self.request.path:
raise ValueError(
"Redirection loop for authenticated user detected. Check that "
"your LOGIN_REDIRECT_URL doesn't point to a login page."
)
return HttpResponseRedirect(redirect_to)
return super().dispatch(request, *args, **kwargs)
def get_success_url(self):
url = self.get_redirect_url()
return url or resolve_url(settings.LOGIN_REDIRECT_URL)
def get_redirect_url(self):
"""Return the user-originating redirect URL if it's safe."""
redirect_to = self.request.POST.get(
self.redirect_field_name,
self.request.GET.get(self.redirect_field_name, '')
)
url_is_safe = url_has_allowed_host_and_scheme(
url=redirect_to,
allowed_hosts=self.get_success_url_allowed_hosts(),
require_https=self.request.is_secure(),
)
return redirect_to if url_is_safe else ''
def get_form_class(self):
return self.authentication_form or self.form_class
def get_form_kwargs(self):
kwargs = super().get_form_kwargs()
kwargs['request'] = self.request
return kwargs
def form_valid(self, form):
"""Security check complete. Log the user in."""
auth_login(self.request, form.get_user())
return HttpResponseRedirect(self.get_success_url())
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
current_site = get_current_site(self.request)
context.update({
self.redirect_field_name: self.get_redirect_url(),
'site': current_site,
'site_name': current_site.name,
**(self.extra_context or {})
})
context.update(csrf(self.request)) #this is the only line that I've added to the vanilla LoginView
return context

您不必为了将类的子类化而覆盖该类的每个方法。如果您只想更改get_context_data方法,那么覆盖该方法就足够了。您需要调用super().get_context_data(**kwargs)来执行LoginView类在该方法中所做的任何操作,然后只需添加如下代码行:

class CustomLoginView(LoginView):
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
context.update(csrf(self.request))
return context

最新更新