Models
Object ownership
If you are interested in the backgrounds of this part, you can have a look at Medium, we posted an article there some time ago.
Abstract class
If you want to keep track of the creator, creation time, last modificator and last modification time,
you can use the abstract class CommonInfo
like this:
from ambient_toolbox.models import CommonInfo
class MyFancyModel(CommonInfo):
...
You then get four fields: created_by
, created_at
, lastmodified_by
, lastmodified_at
.
If you are interested in the details, just have a look at the code base.
Note, that those fields will be automatically added to the update_fields
if you choose to update only a subset of
fields on saving your object. However, you can set the class attribute ALWAYS_UPDATE_FIELDS
to False
on your model to disable this behavior.
Automatic object ownership
If you want to keep track of object ownership automatically, you can use the CurrentRequestMiddleware
:
MIDDLEWARE = (
...
'ambient_toolbox.middleware.current_user.CurrentRequestMiddleware',
...
)
Using this middleware will automatically and thread-safe keep track of the ownership of all models,
which derive from CommonInfo
.
In asynchronous contexts, you may expect a small performance penalty as this
middleware does not state being async_capable
yet.
Django Admin integration
For an easy and worry-free integration, set up your admin classes using CommonInfoAdminMixin
to automatically take care of
the ownership when adding or changing objects via the admin.
It automatically sets the four fields (created_by
, created_at
, lastmodified_by
, lastmodified_at
) to read-only
and ensures that on saving the current object, the creator and/or the last editor are stored correctly.
from ambient_toolbox.admin.model_admins.mixins import CommonInfoAdminMixin
@admin.register(MyModel)
class MyModelAdmin(CommonInfoAdminMixin, admin.ModelAdmin):
pass
Note, that you can derive from this class and overwrite the get_user_obj()
method if your ownership doesn’t use the
default Django user object. This might be the case if you work with a OneToOne relation between the default User
and
your custom one.