Implementing a created by / edited by system


Looking to add a functionality where we can keep with a model instance the user that created it (e.g. fk reference)

What I have considered:

  1. Something with post_save signals, but getting the post_save to have access to the request seems tricky (and perhaps not even a good idea, kind of breaking the abstraction there).
  2. add a field to the forms (as a hidden field or something). Then the view adds request.user to the context (probably with a mixin), I add it to the form behind the scene & save it with the instance.
  3. Create a mixin for my CreateViews/UpdateViews. When I save the object, I add it there & save it again (or just set the attribute & then save).

Any simpler/cleaner way I’m not seeing? I feel I’m going to add it as a form fields, however it’s a bit of a pain to add that to all create/update templates where I want to use it.

EDIT: I guess one option would be to do the opposite? Could I plug a post_save() signal to my subclass of AbstractUser, each time an object is saved and keep sort of a log of saves for each user there? I guess though as times goes on, it’s going to get slower & slower to retrieve which user created a specific object, so that doesn’t scale up very well for my use case. E.g. I will have to display “Created by” in some screens for some object Foo… so after 100 000s of objects gets created, this may not work so welll…

We went with the mechanism of a mixin for all appropriate models with a last_modified_by field. Every view updating that model would then also update that field with request.user.

1 Like

What I end up doing as well. It’s less work; the view already has access to everything needed (the instance to be save/saved, and the request with the user instance). Plus depending on the app, I guess if you put that information in the form as a hidden field, it can be tempered with.

1 Like

And, you can (kinda) implement an “audit” as well.

If you also add a last_modified_on datetime field that is not an auto_now field, you can save that datetime field when the instance is loaded, and compare the original to what should be the updated version in the model’s save method. If the two are the same, then you know that field wasn’t changed.

(It’s not perfect, because there are always ways around model methods, but is generally “good enough”.)