5

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?

2
  • If you aren't willing to include the field in the form class then there is no elegant way of doing it. It will be easiest just to set the value in the view Commented Nov 6, 2013 at 15:35
  • If you don't want to put in forms, you can't handle it in forms. May be override model save method. Commented Nov 6, 2013 at 15:36

4 Answers 4

12

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"]
Sign up to request clarification or add additional context in comments.

Comments

1

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.

Comments

0

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.

Comments

0

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

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

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.