Derek
Derek

Reputation: 12378

How to set form field default value without showing the field in django forms?

I'm using a forms.ModelForm to set a model's attributes. For one of the attributes, I'd like to set a default value, and I want to handle it in the form, thus no default=value on the model attribute in the model class.

On the form, though, I don't want to show the user the value, not even a hidden value, therefore, I can't put the field in fields=(...) and because of that, I can't use the field.initial=value way of setting the default.

I could override validation or saving methods and squeeze a attribute setting in there, but this is not what I would prefer to do.

Are there any "proper" or more elegant ways of solving this problem?

Upvotes: 5

Views: 6904

Answers (4)

Kavin Bharathi
Kavin Bharathi

Reputation: 31

if you just want to set an initial value in the form,

form = MyForm(initial={'field': field_var})

Upvotes: 0

Alasdair
Alasdair

Reputation: 308809

Firstly, exclude the private field from the model form.

class MyModelForm(forms.ModelForm):
    class Meta:
        model = MyModel
        exclude = ["private_field"]

Usually, if I wanted to use a different default value than in the model definition, I would set it in the view.

if form.is_valid():
    my_model = form.save(commit=False)
    my_model.private_field = "default value"
    my_model.save()

If you don't want to set the value in the view, I would suggest overriding the clean method and doing it there. It's not clear to me why you don't want to do this, or what would be more 'proper' about a different approach.

class MyModelForm(forms.ModelForm):
    def clean(self):
        self.instance.private_field = "default value"
        return super(MyModelForm, self).clean()

    class Meta:
        model = MyModel
        exclude = ["private_field"]

Upvotes: 12

You may not want to let the user set his own value to the form, so the best way to keep it like that is excluding the field, like this

class MyForm(forms.ModelForm);
    class Meta:
        model = MyModel
        exclude = [myfield]

and then in the view, lets assume is a Create,

class MyView(CreateView):
     model = MyModel
     form_class = MyForm
     def form_valid(self, form):
         # Save the validated data of your object
         self.object = form.save(commit = False)
         # Update the value of the desired field
         self.object.myfield = # Your value.
         # Save the object to commit the changes
         self.object.save()
         # Response with the success url or whatever is default
         return super(MyView, self).form_valid(form)

In this way you're done, and it's safe for you and for the user as you get full validation in your model.

Upvotes: 1

user1301404
user1301404

Reputation:

In the view after submitting the form:

form(request.POST, initial={'field':value})

Or override clean or clean_field in your form and set the default value there?

1 more thing, you're using a ModelForm, why add a field for that attribute? Just keep it in the model and set the default value.

Upvotes: 0

Related Questions