I intend to override CreateView and UpdateView to set some audit fields
class CreateView(CreateView):
def form_valid(self, form):
form.instance.created_by = self.request.user
# I set below through middleware
project_object = self.request.current_project
form.instance.project = project_object
return super().form_valid(form)
I’m trying to find out what happens if I set form.instance.foo = bar
when foo isn’t a field defined on the model.
So I decided to look at how Model.save()
works. I noticed that Django has a guard against non-defined fields in case of update_fields
was set. non-model fields check.
So I wanted to double check if there is something like that further down the line. I followed Model.save()
to Model._save_table()
. The fields seem to be collected in non_pk
.
I then followed meta.local_concrete_fields
and reached Options.local_fields
.
I wasn’t able to see where local_fields
is set.
Update
Looks like in Modelbase.__ new__() attributes that have a contribute_to_class
method (fields) are collected in contributabe_attrs
. Then these attributes are passed to add_to_class
which calls their contribute_to_class method
. Finally, add_field()
is called, and this populates local_fields
Conclusion
If we set form.instance.foo = bar
given that foo wasn’t defined in the model, foo
will be ignored and not affect the saving process. The exception to this is when we specify update_fields
, there is a check in-place in this case.