In my application I have a CreateView
that must initialize some fields of the model with a default value, different from the default defined inside the model.
I do not want the user to edit the value, thus I put the field in the exclude
list
class AForm(ModelForm):
class Meta:
model = AModel
exclude = ['a_field']
class AView(CreateView):
form_class = AForm
The question is: where do I set the value of a_field
?
I tried to define clean
methods inside AForm
, like thus
class AForm(ModelForm):
[...]
def clean(self):
d = super(AForm, self).clean()
d['a_field'] = 10
return d
however a_field
is set to whatever its default value defined in the model is, rather than 10
. I also tried defining clean_a_field
, but that is simply not executed.
If I remove a_field
from the exclude
list, then the clean
and clean_a_field
will work, but the form won't validate unless I render some <input name="a_field">
inside the template, which is not optimal.
Exclude the field from the form, then in the view you can set the value before you save the form:
form = AForm(request.POST)
if form.is_valid():
new_record = form.save(commit=False)
new_record.a_field = 10
new_record.save()
You also might want to avoid the exclude
list and specify which fields you'd like to include with the fields
attr of the form definition. See the first paragraph here in the docs .
I managed to solve the issue in a way that makes me satisfied, although I'm still not 100% happy with the code.
a_field
is a required (by the model) field, thus it is necessary to render an <input name="a_field">
inside the template. The trick was to make a_field
non-required:
class AForm(ModelForm):
a_field = Field(required=False,
widget=forms.HiddenInput)
class Meta:
model = AModel
def clean_a_field(self):
return 10
This way I can avoid rendering the field in my template, and the form will still validate. And even if the form is rendered with {{ form.as_p }}
, widget=forms.HiddenInput
saves my day.
You set a default value in the model. From the official document ,
a_field = models.CharField(max_length=7, default=''), for example
I have a way to Face this situation. Follow the following process:
Remove 'a_field' from the excludes in AForm.
Do not expose 'a_field' in HTML template. ie Don't give the user option to change the value via Form in Template. This would ensure that normal user's wont modify the value.
To prevent completely, over-ride get_form_kwargs
in the View. This would provide or over-ride your desired value to 'a_field' and save that
eg
class AView(CreateView): form_class = AForm def get_form_kwargs(self): kwargs = super(AView, self).get_form_kwargs() if self.request.method in {'POST', 'PUT'}: # Change post data to over-ride or provide value of 'a_field' data = self.request.POST.copy() data.update({ 'a_field': 'value' }) kwargs['data'] = data return kwargs
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.