I have a view defined as below. I don’t know how I can find out if a field is changed or not. In other words, I don’t know what the <current_company> in code should be.
I knew I could do “initial_company = Company.objects.get(pk=company.pk)” if call form.save() first, but just feel it ugly.
class CompanyChangeView(UpdateView):
model = Company
template_name = 'change-form.html'
form_class = CompanyChangeForm
......
def form_valid(self, form):
# check if owner field is changed on form
if form.cleaned_data['owner'] != <current_company>.owner:
# do something special
company = form.save(commit=False)
company.save()
return #something
Thanks for helping!
If you’re not familiar with what data is stored in a Django-provided CBV, I always recommend people become familiar with the Classy Class-Based View site in addition to reviewing the source code of those views.
In this case, the docs for UpdateView provide the answer you’re looking for.
From the doc, I only found following statement that seems relevant:
“When using UpdateView
you have access to self.object
, which is the object being updated.”
So I added logging below as first line of the form_valid method:
log.info(f’enter form_valid() for {self.object}')
This line printed the company name by its str(). The company was the one I submitted, but the name was the new name I changed on form. This means, the self.object probably represents the new form, not target company object. Is this right? or you actually suggested something else?
I admit, I’m a bit surprised by that behavior.
It looks then that you’d need to override the post
method to save a copy of the original before it gets processed by the form. Something like this would work.
def post(self, request, *args, **kwargs):
self.saved_object = self.get_object()
return super().post(request, *args, **kwargs)
Another option would be to override the __init__
method in the form to save a copy of the original data in the form rather than in the view. The kwargs instance
variable contains the original at the time the form is initialized.
Actually the get_object works in this situation:
def form_valid(self, form):
current_company = self.get_object()
# check if owner field is changed on form
if form.cleaned_data['owner'] != current_company.owner:
# do something special
company = form.save(commit=False)
company.save()
return #something