我对在通用CreateView / UpdateView中可能发生的表单/模型字段验证的位置感到困惑。考虑下面的假设模型。我希望使用我的自定义散列函数对字段secret
进行哈希处理并保存并假设secret
字段的某些验证已完成(未在下面的示例中显示)。我这样做的选择是:
1)在模型保存方法中(我没有在下面显示)
2)在表单的保存方法中(我已在下面显示)
3)form_valid
方法AccountCreateView
(我已在下面展示)
4)如何在通用视图中访问cleaning_data(cleaned_data
可用
只有在调用form_valid
之后
这是正确的方法,包括利弊。我将对updateView
使用相同的表单,在这种情况下,我将在表单上显示其数据之前取消秘密。这应该发生在哪里?
我的模特:
class Account(models.Model):
user = models.ForeignKey(User)
created = models.DateField(auto_now=True)
secret = models.IntegerField()
我的表单:
AccountCreateForm(forms.ModelForm):
secret = forms.CharField(max_length=100)
class Meta:
model = MediaContent
exclude = (secret,user,created)
def save(self, user, debate):
obj = super(AccountCreateView, self).save(commit=False)
obj.user = self.cleaned_data['user']
obj.secret = myHashfunction(self.cleaned_data['secret'])
obj.save()
我的观点:
class AccountCreateView(CreateView):
"""
displays form to create a new search
"""
model = Account
form_class = AccountCreateForm
success_url = reverse_lazy('home')
template_name = 'app/account_form.html'
def form_valid(self, form):
f = form.save(commit=False)
secret=myHashfunction(self.request.POST['secret'])
f.user = self.request.user
f.save()
return super(AccountCreateView,self).form_valid(form)
编辑:
请参阅我的模型和表单的编辑。我在表单中使用的字段不是模型中的字段。 它是一个新的Field,它接受CharField,但模型保存为IntegerField。我的hashfunciton会将charField转换为IntegerField。
答案 0 :(得分:1)
我认为在这种情况下Form
优于ModelForm
,因为排除模型上的每个字段都会使其变得多余。然后,您应该使用secret
对此处的未散列clean_secret
执行任何其他验证。
AccountCreateForm(forms.Form):
secret=forms.CharField(max_length=100)
现在,如果您不再使用ModelForm
,我建议您使用FormView
而不是CreateView
,因为通用CreateView
已经不太合适了。< / p>
class AccountCreateView(FormView):
"""
displays form to create a new search
"""
form_class = AccountCreateForm
success_url = reverse_lazy('home')
template_name = 'app/account_form.html'
def form_valid(self, form):
unhashed_secret = form.cleaned_data['secret']
hashed_secret = myHashfunction(unhashed_secret)
user = self.request.user
# Probably put some extra logic here to check if the user already exists
Account.objects.create(
user=user,
secret=hashed_secret,
)
return super(AccountCreateView,self).form_valid(form)
答案 1 :(得分:0)
以上都不是。执行此操作的正确位置在表单的clean_secret
方法中。这是任何与字段相关的验证和转换的地方。只需返回该方法的散列值即可。