Django自定义UpdateView移除帮助文本报错:列表索引需为整数而非字符串
问题原因与解决方案
为什么UpdateView的代码会报错?
你遇到的list indices must be integers or slices, not str错误,核心原因是UpdateView和表单类的self.fields在__init__阶段的形态完全不同:
- 你的
CustomUserForm是UserCreationForm(本质是ModelForm)的子类,当调用super().__init__(*args, **kwargs)后,表单内部会把Meta类里定义的fields列表转换成一个字典,键是字段名,值是对应的字段对象,所以你可以用self.fields[fieldname]通过字符串索引访问字段。 - 而
UpdateCustomUser是UpdateView的子类,在它的__init__方法执行时,self.fields还是你在类定义里写的列表['username', 'first_name', 'last_name', 'email'],列表只能用整数或切片做索引,你用字符串去访问自然就会报错。
两种可行的解决办法
方法1:重写UpdateView的get_form方法
在get_form方法里,表单已经被实例化完成,此时可以安全地修改字段的帮助文本:
class UpdateCustomUser(UpdateView): model = User fields = ['username', 'first_name', 'last_name', 'email'] template_name = 'auth/user_update_form.html' context_object_name = 'current_user' def get_object(self, queryset=None): return self.request.user def get_form(self, form_class=None): # 获取父类生成的表单实例 form = super().get_form(form_class) # 遍历字段移除帮助文本 for fieldname in ['username', 'first_name', 'last_name', 'email']: form.fields[fieldname].help_text = None return form
方法2:自定义ModelForm并关联到UpdateView
和你写CustomUserForm的思路一致,先定义一个用于更新的ModelForm,在表单的__init__里处理帮助文本,再让UpdateView使用这个表单:
from django import forms from django.contrib.auth.models import User class CustomUserUpdateForm(forms.ModelForm): class Meta: model = User fields = ['username', 'first_name', 'last_name', 'email'] def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) for fieldname in ['username', 'first_name', 'last_name', 'email']: self.fields[fieldname].help_text = None # 然后修改你的UpdateView class UpdateCustomUser(UpdateView): model = User form_class = CustomUserUpdateForm # 替换成自定义表单 template_name = 'auth/user_update_form.html' context_object_name = 'current_user' def get_object(self, queryset=None): return self.request.user
这两种方法都能达到你移除帮助文本的目的,第二种方法更符合Django“表单负责表单逻辑”的设计思路,也更易维护。
内容的提问来源于stack exchange,提问作者Enrico
相关产品推荐
相关产品推荐

