我正在使用UpdateView来更新一系列字段。但是,我只希望将已修改的字段保存到数据库中。如果在更新过程中没有为字段提供值,我希望将前一个值用作默认值。如果为字段提供了新值,则只应更新该字段。我该如何完成这项工作?
#views.py
class AccountUpdate(UpdateView):
""" Updates an account; unchanged fields will not be updated."""
context_object_name = 'account'
form_class = UpdateForm
template_name = 'accounts/update_account.html'
success_url = '/accounts/home'
def get_object(self, queryset=None):
return self.request.user
def form_valid(self, form):
clean = form.cleaned_data
#encrypt plain password
form.instance.password = hash_password(clean['password'])
context = {}
self.object = context.update(clean, force_update=False)
return super(AccountUpdate, self).form_valid(form)
#templates
{% extends 'base.html' %}
<title>{% block title %}Update Account{% endblock %}</title>
{% block content %}
{{ account.non_field_errors }}
<div class="errors" style="list-style-type: none;">
{% if account.first_name.errors %}{{ account.first_name.errors }}{% endif %}
{% if account.last_name.errors %}{{ account.last_name.errors }}{% endif %}
{% if account.email.errors %}{{ account.email.errors }}{% endif %}
{% if account.password.errors %}{{ account.password.errors }}{% endif %}
{% if account.username.errors %}{{ account.username.errors }}{% endif %}
</div>
<form action="" name="edit" method="post">
{% csrf_token %}
<ul>
<li>Fullname</li>
<li> {{ form.first_name }}{{ form.last_name }}</li>
<li>Email</li>
<li>{{ form.email }}</li>
<li>Password</li>
<li>{{ form.password }}</li>
<li>Username</li>
<li>{{ form.username }}</li>
</ul>
<ul>
<li><input type="submit" value="update account"></li>
</ul>
</form>
<ul>
<li class="nav"><a href="/accounts/">cancel changes</a></li>
</ul>
{% endblock %}
所有字段也在models.py
中声明为必需。目前,只有我为每个字段提供值时,表单才有效。
答案 0 :(得分:5)
我在更新过程中使用自定义哈希来加密密码。当我访问编辑页面并点击更新按钮时,当前加密形式的旧密码将被重新加密,从而丢失旧密码
我会通过在表单中不包含password
本身来解决这个问题。相反,我会添加一个新字段(类似new_password
)以允许输入新密码。然后,在is_valid
方法中,将密码设置为该字段的哈希值(如果有内容)。
您还应该使用sensitive value filtering工具来防止用户密码显示在电子邮件错误报告中。
class UpdateForm(forms.ModelForm):
class Meta:
model = user
fields = ('first_name', 'last_name', 'email', 'username')
new_password = forms.CharField(required=False, widget=forms.widgets.PasswordInput)
然后在你看来:
@sensitive_variables('new_password')
@sensitive_post_parameters('new_password')
def form_valid(self, form):
clean = form.cleaned_data
new_password = clean.get('new_password')
if new_password:
#encrypt plain password
form.instance.password = hash_password(new_password)
return super(AccountUpdate, self).form_valid(form)
答案 1 :(得分:0)
最简单的方法是使用已有的字段预先填充字段。
使用{{ account.name }}
或其他任何内容在模板上执行此操作。