Django自定义User模型使用UpdateView无法同步更新数据库问题
问题:自定义User模型通过UpdateView更新后数据库未保存修改
问题描述
通过继承AbstractUser实现自定义User模型,使用UpdateView进行更新操作时,点击更新按钮页面刷新后临时显示修改内容,但数据库未实际更新;重新打开页面后,显示的信息仍为修改前的状态。使用Django 4.2.8版本。
相关代码
models.py
class UserManager(models.Manager): def New_Requests(self): return super.get_queryset().filter(is_seller="I") # 存在语法错误 class User(AbstractUser): nickname = models.CharField(max_length=50,verbose_name="Nick Name",default='User') is_seller_status = ( ('N','Not accepted'), ('I','Investigate'), ('A','Accepted') ) is_seller = models.CharField(default='N',max_length=1,choices=is_seller_status,verbose_name='seller') user_id = models.UUIDField(default = uuid.uuid4,editable = False,unique=True) profile = models.ImageField(upload_to="user_profile",blank=True,null=True) admin_reject_reason = models.TextField(default='Not reviewed yet')
views.py
class AccountView(LoginRequiredMixin,UpdateView): model = User form_class = UserProfileForm template_name = "user/profile.html" success_url = reverse_lazy("user:profile") def get_object(self): return User.objects.get(pk = self.request.user.pk) def get_form_kwargs(self): kwargs = super(AccountView, self).get_form_kwargs() kwargs['user'] = self.request.user # Pass 'user' directly to the form return kwargs
forms.py
class UserProfileForm(UserChangeForm): #User profileform def __init__(self,*args, **kwargs): user = kwargs.pop('user') super(UserProfileForm, self).__init__(*args, **kwargs) if not user.is_superuser: self.fields['first_name'].disabled = True self.fields['last_name'].disabled = True #self.fields['email'].help_text = "Change it if it was neccessary" self.fields['email'].disabled = True self.fields['is_seller'].disabled = True class Meta: #specifing the model and fields model = User fields = ['profile','nickname','username','email','first_name','last_name', 'is_seller']
urls.py
app_name = "user" urlpatterns = [ ... path('profile/',AccountView.as_view(),name='profile'), ... ] urlpatterns += static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
profile.html
{% extends 'user/base.html' %} {% load static %} {% load crispy_forms_tags %} {% block content %} <!-- Begin Page Content --> <div class="container-fluid"> <!-- Page Heading --> <div class="d-sm-flex align-items-center justify-content-between mb-4"> <h1 class="h3 mb-0 text-gray-800">Profile</h1> </div> <div class="col-md-12"> <div class = "card card-primary"> <div class="card-header"> <h3 class = "card-title mb-0 float-left">User Update</h3> </div> <div class="card-body"> <form method="post" enctype="multipart/form-data">{% csrf_token %} <div class="row"> <div class="col-6"> {{ form.username|as_crispy_field }} </div> <div class="col-6"> {{ form.email|as_crispy_field }} </div> <div class="col-6"> {{ form.first_name|as_crispy_field }} </div> <div class="col-6"> {{ form.last_name|as_crispy_field }} </div> <div class="col-6"> {{ form.is_seller|as_crispy_field }} </div> <div class="col-6"> {{ form.profile|as_crispy_field }} </div> </div> <input class="btn btn-success" type="submit" value="Update"> </form> </div> </div> </div> </div> <!-- /.container-fluid --> <!-- End of Main Content --> {% endblock %}
settings.py
AUTH_USER_MODEL = "user.User" AUTH_PROFILE_MODULE = "user.User"
原因分析
- 表单字段缺失导致隐性验证失败:表单
fields包含了nickname,但模板未渲染该字段,提交时缺失该字段值。由于nickname模型字段未设置blank=True,表单触发验证失败但未显示错误提示,导致数据未保存。 - UserManager语法错误:
New_Requests方法中super.get_queryset()缺少括号,应为super().get_queryset(),虽不直接影响UpdateView,但属于代码隐患。 - 用户实例缓存问题:即使数据保存成功,
request.user可能处于Django缓存中,重定向后显示缓存数据而非最新数据库数据。
解决方案
1. 补充模板中缺失的表单字段
在profile.html的表单中添加nickname字段的渲染:
<div class="col-6"> {{ form.nickname|as_crispy_field }} </div>
2. 修复UserManager语法错误
修改models.py中的New_Requests方法:
def New_Requests(self): return super().get_queryset().filter(is_seller="I")
3. 重写form_valid方法确保保存并刷新缓存
在views.py的AccountView中添加form_valid方法:
def form_valid(self, form): # 保存表单数据到数据库 self.object = form.save() # 刷新request.user实例,更新缓存 self.request.user.refresh_from_db() return super().form_valid(form)
4. 添加表单错误提示(可选)
在模板表单顶部添加错误提示,方便排查验证问题:
{% if form.errors %} <div class="alert alert-danger mb-3"> {{ form.errors }} </div> {% endif %}
验证步骤
修改完成后重启服务:
- 修改用户信息(如用户名、昵称)并提交
- 直接查看数据库中对应的User记录,确认是否更新
- 重新打开页面或刷新,确认显示最新数据
内容的提问来源于stack exchange,提问作者Kian Jafari
相关产品推荐
相关产品推荐

