如何正确重写Django Registration Redux的RegistrationView添加注册前置校验
实现方案说明
你当前的子类化扩展思路是正确的,但存在一个兼容问题,同时有更符合Django类视图设计规范的实现方式:
现有写法的问题
原RegistrationView的register方法约定返回值为新创建的用户实例,你在条件不满足时直接返回重定向响应对象,会导致后续接收返回值的逻辑抛出类型异常,无法正常运行。
推荐实现方式(最优)
重写类视图的form_valid方法,该方法会在表单校验通过后、执行注册逻辑前触发,本身支持直接返回响应对象,对原代码侵入性最低:
from django.contrib import messages from django.shortcuts import redirect from registration.backends.default.views import RegistrationView class CustomRegistrationView(RegistrationView): def form_valid(self, form): # 执行自定义条件校验 if not test_for_condition(self.request): messages.error(self.request, "无法完成注册操作。", extra_tags='errortag') return redirect('/access/register') # 校验通过后执行原有注册逻辑 return super().form_valid(form)
可选实现方式(适合需要耦合注册内部逻辑的场景)
如果你确实需要把校验逻辑放在register方法内执行,可以先在校验失败时抛出自定义异常,再在上层方法中捕获处理:
from django.core.exceptions import PermissionDenied class CustomRegistrationView(RegistrationView): def register(self, form): if not test_for_condition(self.request): raise PermissionDenied("注册条件不满足") return super().register(form) def form_valid(self, form): try: return super().form_valid(form) except PermissionDenied as e: messages.error(self.request, str(e), extra_tags='errortag') return redirect('/access/register')
补充说明
Django类视图实例在完成初始化后,所有生命周期方法(dispatch、get、post、form_valid、register等)中都可以直接通过self.request获取到当前请求对象,和函数视图的入参request完全一致,不需要额外做传递处理。
内容的提问来源于stack exchange,提问作者Jason Howard
相关产品推荐
相关产品推荐

