Versioned Models

I want to create a new entry when a model is updated instead of updating the actual model.
Is there a way to detecet when a save would update a model instead of saving it?

I would like to do this based on the Class so I can create a VersionMixin.
The Class should point to the prev. Version and the next if there is one. Like a chained list.

But somehow my save method is called twice - first the object is created and then its updated again.
I am not sure why this happens? Could this be due many-to-many fields?

Is something like this what you want?

obj = Model.objects.get(id=1)
obj.previous_id = obj.id
obj.id = None
# Update other fields
...
obj.save()

UPDATE vs INSERT is covered in https://docs.djangoproject.com/en/3.0/ref/models/instances/#how-django-knows-to-update-vs-insert

1 Like

There are also a number of pre-built packages that may satisfy your requirements. Take a look at the Versioning Grid on Django Packages

1 Like

I guess I shot myself in the Foot with the many-to-many fields I created.

In the create view I added the many-to-many relationships from form_valid() - so I had to save the object first. Then I called the super method, which also saved the model.

Now if I created a new model on the first run I wouldn’t have a id/pk but on the second run I would have one.
When creating an object I would always create a second version of it.

I rewrote the form_valid method to return the HTTPRedirect like the FormMixin does and now I can just check in the save method if the ID is set.

Hard to spot this one…

:+1:

You should always redirect after POST success as per https://en.wikipedia.org/wiki/Post/Redirect/Get

Couple general thoughts on this for possible future reference -

  • In the documentation for the save() method, see the paragraphs on the ‘commit=False’ parameter.

  • You don’t need to wait until the end of your method to call super. Super is a function call, you can call it anywhere in your method where it makes the most sense to do so. (Not relevant in this specific case, just something you want to remember when writing code.)

1 Like

Well I am still hitting the problem that the save method runs twice. I guess its the many-to-many fields after all. Version 1 remembers the m2m fields, Version 2 does this two, but Version 3 (which shouldn’t be created in first place) forgets about the m2m cases.

:right_anger_bubble:

Nope just shot myself in the foot again. Of couse I forgot to change the Code in the UpdateView… well I guess I could have started here since I know when I update because I am using the UpdateView…

@KenWhitesell and @adamchainz Thanks for answering all these questions in the forum! It really helps to read your answers