How to access current object from form_valid()

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