Django表单无法更新User数据库的问题排查与解决
Django User模型表单更新失败的修复方案
核心问题定位
- 表单提交路径错误:模板里的表单
action="/"会把请求发到根路径,而非处理更新的upform视图(带用户id参数),导致提交的数据未进入更新逻辑。 - 表单字段风险:使用
fields="__all__"会暴露User模型的敏感字段(如id、password),其中password明文提交无法自动哈希,id被修改会导致数据混乱。 - 权限装饰器用法错误:
@permission_required('is_superuser')参数不符合规范,正确权限校验应使用权限codename或直接判断超级用户身份。
分步修复代码
1. 修正forms.py
限制可修改字段,处理密码哈希逻辑:
from django import forms from django.contrib.auth.models import User class UpdateForm(forms.ModelForm): password = forms.CharField(widget=forms.PasswordInput(), required=False) class Meta: model = User # 只保留允许修改的字段 fields = ['username', 'email', 'first_name', 'last_name'] def save(self, commit=True): user = super().save(commit=False) # 仅当提交新密码时才进行哈希处理 if self.cleaned_data['password']: user.set_password(self.cleaned_data['password']) if commit: user.save() return user
2. 修正views.py
修复权限校验,优化对象获取逻辑:
from django.contrib.auth.decorators import permission_required from django.shortcuts import get_object_or_404, redirect, render from django.contrib.auth.models import User from .forms import UpdateForm # 使用正确的权限codename,或改用user.is_superuser判断 @permission_required('auth.change_user', raise_exception=True) def upform(request, id): # 用get_object_or_404避免用户不存在时抛出异常 emp = get_object_or_404(User, id=id) if request.method == 'POST': frm = UpdateForm(request.POST, instance=emp) if frm.is_valid(): frm.save() return redirect('/') else: frm = UpdateForm(instance=emp) return render(request, 'examp.html', {'frm': frm, 'emp': emp})
3. 修正examp.html模板
让表单提交到正确的更新视图:
{% load static %} <!DOCTYPE html> <html lang="zh-CN"> <head> <meta charset="UTF-8"> <title>更新用户信息</title> <link rel="stylesheet" href="{% static '/examp.css' %}"> <style> td,th{ border:1px solid; text-align:center; padding:10px; } </style> </head> <body> {% include 'include/header.html' %} <!-- 用{% url %}标签生成正确的视图路径(需先在urls.py中给upform命名) --> <form action="{% url 'upform' id=emp.id %}" method="POST"> {% csrf_token %} {{ frm.as_p }} <input type="submit" value="提交更新"> </form> </body> </html>
4. 补充urls.py配置
确保视图路径正确并命名:
from django.urls import path from . import views urlpatterns = [ # 其他路径配置... path('user/update/<int:id>/', views.upform, name='upform'), ]
额外注意事项
- 测试时需使用拥有
auth.change_user权限的超级用户登录。 - 若无需修改密码,可删除forms.py中的password字段及对应处理逻辑。
- 可添加Django messages框架实现更新成功的提示反馈。
内容的提问来源于stack exchange,提问作者Jemesh Khatik
相关产品推荐
相关产品推荐

