Django表单设置remember_me报错:'SignInForm'无'request'属性
解决Django表单中'request'属性不存在的问题
问题原因
Django的Form类默认不会自动绑定request对象,你在clean_remember_me方法中直接访问self.request,必然会抛出'SignInForm' object has no attribute 'request'的错误。
解决方案
要在表单中使用request,需要手动将其从视图传递到表单实例中,具体步骤如下:
1. 修改表单类,添加request属性
在SignInForm的__init__方法中接收request参数,并保存为实例属性:
class SignInForm(forms.Form): remember_me = forms.BooleanField(widget=forms.CheckboxInput(), label=_('Remember me'), required=False) def __init__(self, *args, **kwargs): # 从kwargs中取出request,再调用父类初始化方法 self.request = kwargs.pop('request', None) super().__init__(*args, **kwargs) def clean_remember_me(self): remember_me = self.cleaned_data['remember_me'] if not remember_me and self.request: self.request.session.set_expiry(0) return remember_me # 必须返回清理后的数据,否则cleaned_data中会丢失该字段
2. 在视图中传递request给表单
重写LogInView的get_form_kwargs方法,将当前请求对象加入表单的初始化参数:
class LogInView(GuestOnlyView, FormView): template_name = 'log_in.html' form_class = SignInForm def get_form_kwargs(self): kwargs = super().get_form_kwargs() # 将request传递给表单 kwargs['request'] = self.request return kwargs
额外建议
其实修改session过期时间的逻辑,放在视图的form_valid方法中更符合Django的设计模式(表单负责验证数据,视图处理业务逻辑),示例如下:
class LogInView(GuestOnlyView, FormView): template_name = 'log_in.html' form_class = SignInForm def form_valid(self, form): # 先处理登录逻辑... remember_me = form.cleaned_data.get('remember_me') if not remember_me: self.request.session.set_expiry(0) return super().form_valid(form)
内容的提问来源于stack exchange,提问作者SOFArminRh
相关产品推荐
相关产品推荐

