Q: where to hash form data before saving the model in createview in Django? I am a little confused with where validation of form/model fields can happen in generic CreateView/UpdateView. Consider my hypothetical model below. I want the field secret to be hashed using my custom hashfunction and saved and assume some validation for secret field is done(NOT shown in the example below). My options to do this are:
1) in the model save method (I have not shown this below)
2) in the form's save method (I have shown below)
3) in the form_valid method of AccountCreateView (I have shown below)
4) how can I access the cleaned_data in the generic views (cleaned_data is available
only after form_valid is called)
Which is the right way to do it, both pros and cons. I will use the same form for updateView, in which case I will unhash the secret before displaying its data on the form. where this should happen?
My model:
class Account(models.Model):
    user = models.ForeignKey(User)
    created = models.DateField(auto_now=True)
    secret = models.IntegerField() 

My form:
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()

My view:
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)

EDIT:
please see the edit to my model and form. the field I use in form is not the field in model.
It is a new Field, that takes CharField but the model  saves as IntegerField. my hashfunciton will convert the charField to IntegerField. 

A: I think in this case Form is the better than ModelForm, as excluding every field on your model makes it redundant. You should then do any additional validation for the un-hashed secret here with clean_secret.
AccountCreateForm(forms.Form):
    secret=forms.CharField(max_length=100)

Now, if you are not using the ModelForm anymore, I would suggest using FormView over CreateView as the generic CreateView has become less of a good fit.
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)


A: None of the above. The correct place to do this is in the clean_secret method of the form. That is the place for any field-related validation and conversion. Simply return the hashed value from that method.
