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?
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"]
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With