在Django的createview中保存模型之前,在哪里哈希表单数据?

时间:2014-04-21 19:30:54

标签: django django-models django-forms django-class-based-views django-validation

我对在通用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。

2 个答案:

答案 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方法中。这是任何与字段相关的验证和转换的地方。只需返回该方法的散列值即可。