django - Django 表单数据未保存到数据库
问题描述
我试图允许用户使用城市、描述、网站地址等更新他们的用户资料。
使用 Django 2.0,我在一个视图中有两种形式:
EditProfileForm (EPF) = 电子邮件表格、姓名和密码
EditProfileForm 似乎能够保存数据。但是,EditUserProfile 似乎没有。
EditUserProfile (EUP) = 更多用户信息的表格,例如城市、描述、网站地址等。
输入数据并提交表单时,EUP 表单的数据似乎没有保存或更新用户信息
我也尝试过以下方法:
if form_EUP.is_valid():
obj = form_EUP.save(commit=False)
obj.user = request.user
obj.save()
并尝试创建与 RegistrationForm 中使用的格式类似的自定义保存方法,但我没有运气
我是 django 框架的初学者,所以任何想法都会非常感激,干杯。
视图.py
def edit_profile(request):
if request.method == 'POST':
form_EPF = EditProfileForm(request.POST, instance=request.user)
form_EUP = EditUserProfile(request.POST, instance=request.user)
if form_EPF.is_valid():
form_EPF.save()
return redirect(reverse('accounts:view_profile'))
if form_EUP.is_valid():
form_EUP.save()
return redirect(reverse('accounts:view_profile'))
else:
form_EPF = EditProfileForm(instance=request.user)
form_EUP = EditUserProfile(instance=request.user)
args = {'form_EPF': form_EPF, "form_EUP": form_EUP}
return render(request, 'accounts/edit_profile.html', args)
表格.py
class RegistrationForm(UserCreationForm):
email = forms.EmailField(required=True)
class Meta:
model = User
fields = (
'username',
'first_name',
'last_name',
'email',
'password1',
'password2'
)
def save(self, commit=True):
user = super(RegistrationForm, self).save(commit=False)
user.first_name = self.cleaned_data['first_name']
user.last_name = self.cleaned_data['last_name']
user.email = self.cleaned_data['email']
if commit:
user.save()
return user
class EditProfileForm(UserChangeForm):
class Meta:
model = User
fields = (
'email',
'first_name',
'last_name',
'password',
)
class EditUserProfile(ModelForm):
description = forms.CharField(required=False)
city = forms.CharField(required=False)
website = forms.URLField(required=False)
class Meta:
model = UserProfile
fields = (
'description',
'city',
'website',
'image',
)
模型.py
class UserProfile(models.Model):
user = models.OneToOneField(User, on_delete=models.CASCADE)
description = models.CharField(max_length=100, default='')
city = models.CharField(max_length=100, default='')
website = models.URLField(default='')
phone = models.IntegerField(default=0)
image = models.ImageField(upload_to='profile_image', blank=True)
def __str__(self):
return self.user.username
def create_profile(sender, **kwargs):
if kwargs['created']:
user_profile = UserProfile.objects.create(user=kwargs['instance'])
post_save.connect(create_profile, sender=User)
edit_profile.html
{% block body %}
<div class="container">
<h1>Edit profile</h1>
<form method="post">
{% csrf_token %}
{{ form_EPF.as_p }}
{{ form_EUP.as_p }}
<button type="submit">Submit</button>
</form>
</div>
{% endblock %}
解决方案
这里:
if form_EPF.is_valid():
form_EPF.save()
return redirect(reverse('accounts:view_profile')) # !!!!!
if form_EUP.is_valid():
form_EUP.save()
return redirect(reverse('accounts:view_profile'))
您将在保存用户表单后返回,因此配置文件表单确实从未保存(除非用户表单无效 xD)。
你要:
if form_EPF.is_valid() and form_EUP.is_valid():
form_EPF.save()
form_EUP.save()
return redirect(reverse('accounts:view_profile')) # !!!!!
另外,你有这个不起作用:
form_EUP = EditUserProfile(request.POST, instance=request.user)
您正在传递一个 ̀Useras
实例, but the form expects a
UserProfile 。
而且 - 虽然它不会阻止你的代码运行 - 你肯定要三思而后行你的命名。“EditProfileForm”编辑用户,因此它应该真正命名为“EditUserForm”(或“UserEditForm”等),并且您视图中的变量并没有更好 - ̀form_EPF and
form_EUP requires active thinking to parse the suffix and match it with the (already counter-intuitive) form class names, and you _don't_ want to have to do any effort to understand what a name means when reading code. Just use the all_lower form of the class instead, so assumin you renamed your form classes to a much saner
UserEditForm and
ProfileEditForm , the variables would be
user_edit_form and
profile_edit_form`。这确实是额外的几次击键,但平均而言,您阅读代码的时间比编写代码的时间多 1000 倍,因此确实值得优化阅读。
推荐阅读
- html - 为什么右侧没有边距?
- python - python 在 Azure Pipelines 的“.py”中找不到“__main__”模块
- php - 使用 Shell 调用前端控制器 yii2 不起作用
- hive - 当蜂巢插入中途失败时会发生什么?
- javascript - 如何从 Electron 应用程序在 Chrome 中打开链接?
- javascript - 对许多重新渲染和功能的反应原生应用程序在状态变化时保持运行
- visual-studio-code - VSCode:打开文件时保持焦点在源代码管理Viewlet
- javascript - ReferenceError:未定义通道
- excel - VBA 用户表单代码仅在工作表可见时才有效
- angular - Angular 9 取消 HTTP 请求