Wagtail中ModelAdmin的get_edit_handler无法获取request的解决方法
解决Wagtail ModelAdmin中无法获取request对象的问题
问题根源
ModelAdmin的get_edit_handler方法设计用于构建编辑界面的字段布局,默认不会传递有效的request参数(因此你打印出None),且你之前的尝试存在两个关键错误:
- 让
ModelAdmin继承EditHandler是错误的,二者职责不同,不应混用; - 直接将
form_class赋值为表单实例(RequestForm(request=request))不符合规范,且此时request本身就是None,导致表单中获取的request为None,触发'NoneType' object has no attribute 'user'错误。
正确解决方案:通过自定义EditView传递request给表单
我们可以重写自定义EditView的get_form_kwargs方法,将请求上下文的request传递给表单,具体步骤如下:
1. 自定义表单类(接收request参数)
from wagtail.admin.forms import WagtailAdminModelForm class RequestForm(WagtailAdminModelForm): class Meta: model = Somemodel fields = "__all__" def __init__(self, *args, **kwargs): # 从kwargs中取出request并保存 self.request = kwargs.pop("request") super().__init__(*args, **kwargs) # 此处可以正常使用self.request.user进行逻辑处理 # 示例:限制非超级用户无法修改指定字段 if not self.request.user.is_superuser: self.fields["sensitive_field"].widget.attrs["disabled"] = True
2. 自定义EditView(传递request到表单)
from wagtail.admin.views.edit import SaveContinueEditView class CustomSaveContinueEditView(SaveContinueEditView): def get_form_kwargs(self): # 调用父类方法获取基础kwargs kwargs = super().get_form_kwargs() # 将当前请求的request对象加入kwargs,传递给表单 kwargs["request"] = self.request return kwargs
3. 配置ModelAdmin
from wagtail.contrib.modeladmin.options import ModelAdmin class SomemodelAdmin(ModelAdmin): model = Somemodel list_display = ("field",) # 指定自定义的EditView类 edit_view_class = CustomSaveContinueEditView # 指定自定义表单类 form_class = RequestForm
另一种简洁方案:重写ModelAdmin的get_form方法
如果你不想自定义EditView,也可以直接重写ModelAdmin的get_form方法,将request传递给表单的构造参数:
class SomemodelAdmin(ModelAdmin): model = Somemodel list_display = ("field",) edit_view_class = SaveContinueEditView form_class = RequestForm def get_form(self, request, obj=None, **kwargs): # 将request加入表单的构造参数 kwargs["request"] = request return super().get_form(request, obj, **kwargs)
这种方式更简洁,同样能让表单获取到有效的request对象。
内容的提问来源于stack exchange,提问作者Leon_idas
相关产品推荐
相关产品推荐

