logging admin accesses

186 views
Skip to first unread message

Larry Martell

unread,
Dec 14, 2023, 2:44:51 PM12/14/23
to django...@googlegroups.com
Is there a way to capture all admin changes (add, change, delete). I have some middleware that gets called on any admin add, change, or delete, but I have not figured out a way to capture specifically what was done, something like: model, PK, action, e.g.

user, 12, change, first name changed
user, 15, add
user, 24, delete

I am looking for something generic that will work for all models under admin control.

Mike Dewhirst

unread,
Dec 14, 2023, 5:50:31 PM12/14/23
to django...@googlegroups.com
Top posting because of phone email client.

Have you seen the Admin history? Might be already logged for you.

Mike

--
(Unsigned mail from my phone)

--
You received this message because you are subscribed to the Google Groups "Django users" group.
To unsubscribe from this group and stop receiving emails from it, send an email to django-users...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/django-users/CACwCsY5tDc6ZJihTJFmrmus4PG7f_HCXewN-pQr3T-WcMGG4ZA%40mail.gmail.com.

Larry Martell

unread,
Dec 14, 2023, 6:02:05 PM12/14/23
to django...@googlegroups.com
On Thu, Dec 14, 2023 at 5:49 PM Mike Dewhirst <mi...@dewhirst.com.au> wrote:
Top posting because of phone email client.

Have you seen the Admin history? Might be already logged for you.

Is that programically accessible? I want to record it in the database. 

Vitaly Bogomolov

unread,
Dec 15, 2023, 8:38:49 AM12/15/23
to Django users

Is that programically accessible? I want to record it in the database. 


from django.contrib.admin.models import LogEntry

logs = LogEntry.objects.all() #or you can filter, etc.

 

Larry Martell

unread,
Dec 15, 2023, 9:48:07 AM12/15/23
to django...@googlegroups.com
On Thu, Dec 14, 2023 at 5:49 PM Mike Dewhirst <mi...@dewhirst.com.au> wrote:
Top posting because of phone email client.

Have you seen the Admin history? Might be already logged for you.

Thanks, this is useful, but it does not seem to be logging everything. We have a custom user admin page that updates a few models in addition to User: UserInfo, UserExtendProduct, and UserRole. If I add a new user I see this:

+-----------+-------------+-------------+-----------------------------------------------------------------------------------------------------------------------------+-----------------+---------+
| object_id | object_repr | action_flag | change_message                                                                                                              | content_type_id | user_id |
+-----------+-------------+-------------+-----------------------------------------------------------------------------------------------------------------------------+-----------------+---------+
| 3         | x           |           1 | [{"added": {}}, {"added": {"name": "user info", "object": "x"}}, {"added": {"name": "user extend product", "object": "x"}}] |               4 |       1 |
+-----------+-------------+-------------+-----------------------------------------------------------------------------------------------------------------------------+-----------------+---------+


It shows that a row in User, UserInfo, and UserExtendProdct were added, but it does not show what was added to the latter 2, and it does not show that rows were added to UserRole.

When I modify a user and cause UserRole to be updated I see this:

+-----------+-------------+-------------+----------------+-----------------+---------+
| object_id | object_repr | action_flag | change_message | content_type_id | user_id |
+-----------+-------------+-------------+----------------+-----------------+---------+
| 3         | x           |           2 | []             |               4 |       1 |
+-----------+-------------+-------------+----------------+-----------------+---------+

No info about that row being added. If I cause a row in UserRole to be deleted I get the exact same entry, so I cannot distinguish between an add and a delete and I can't see what was added or deleted. 

But if I cause a row in UserInfo or UserExtendProduct to be added I see this:

+-----------+-------------+-------------+-----------------------------------------------------------------------------------------------------------------------------+-----------------+---------+
| object_id | object_repr | action_flag | change_message                                                                                                              | content_type_id | user_id |
+-----------+-------------+-------------+-----------------------------------------------------------------------------------------------------------------------------+-----------------+---------+
| 3         | x           |           1 | [{"added": {}}, {"added": {"name": "user info", "object": "x"}}, {"added": {"name": "user extend product", "object": "x"}}] |               4 |       1 |
+-----------+-------------+-------------+-----------------------------------------------------------------------------------------------------------------------------+-----------------+---------+

Shows an add, but not what was added.

So my questions are:
-how can I get it to show the details of what was added or changed
-why are updates to UserInfo and UserExtendProduct shown, but updates to UserRole are not?

Thanks!

Mike Dewhirst

unread,
Dec 15, 2023, 8:38:41 PM12/15/23
to django...@googlegroups.com
You seem to be asking for a full history 'system'. 

I think the Admin history exists to show a bit of history with a link to go back to the change form where it happened.

Full history needs to be specified fairly carefully so it doesn't bog the system down. For example, every write costs a performance hit. Also, how resilient must it be to cope with database schema changes? How is it going to be used in practice? What are the benefits and are they worth the effort. 

I have worked through some of this in my current project and decided to create separate 'mirror' tables for only the critical information and automate data collection for others in a plain text field for archival.

It can be quite open ended and might reward very aggressive specification.

Cheers

Mike



--
(Unsigned mail from my phone)



--
You received this message because you are subscribed to the Google Groups "Django users" group.
To unsubscribe from this group and stop receiving emails from it, send an email to django-users...@googlegroups.com.

Mike Dewhirst

unread,
Dec 15, 2023, 9:03:22 PM12/15/23
to django...@googlegroups.com
Just thinking about it again ... you could look at the Admin source to see how it is working now and perhaps find a way to include the missing info in a pre-save signal.

Also, I found django-simple-history online but I suppose you have seen that already.

M

Larry Martell

unread,
Dec 18, 2023, 2:49:18 PM12/18/23
to django...@googlegroups.com
For pages under admin control, yes, we need a full system history. For other tables what we need is more narrowly defined. I have very clear specs on what I need to log. ATM performance is not a concern. 

Larry Martell

unread,
Dec 18, 2023, 2:49:50 PM12/18/23
to django...@googlegroups.com
No, I have not see django-simple-history - thanks for the pointer - will check it out. 

Larry Martell

unread,
Dec 18, 2023, 4:19:29 PM12/18/23
to django...@googlegroups.com
django-simple-history is close to what we need. The one issue I see
(so far) is that it does not support tables that are created behind
the scenes by django to handle one to many relations that do not have
models. Does anyone know how to maintain history on those?

Mike Dewhirst

unread,
Dec 18, 2023, 5:27:28 PM12/18/23
to django...@googlegroups.com
Those many-to-many relations most certainly can have models and all of mine always do. 

It is more explicit to do so but more importantly they generally carry essential real-world information about the relationship itself.

I haven't looked at django-simple history beyond deciding to roll my own but it may well cover m2m tables if you add the models explicitly. 
--
You received this message because you are subscribed to the Google Groups "Django users" group.
To unsubscribe from this group and stop receiving emails from it, send an email to django-users...@googlegroups.com.

Larry Martell

unread,
Dec 18, 2023, 5:51:56 PM12/18/23
to django...@googlegroups.com
Hmmm, in my case I do not see any models for those in any of my models.py files. Where would I expect to find them? 

Mike Dewhirst

unread,
Dec 18, 2023, 7:24:37 PM12/18/23
to django...@googlegroups.com
On 19/12/2023 9:51 am, Larry Martell wrote:
Hmmm, in my case I do not see any models for those in any of my models.py files. Where would I expect to find them?

You have to write them yourself. The best way is to run manage.py inspectdb > models.txt then extract the m2m models from there. In theory and provided you follow the advice at the top of the output ...

# This is an auto-generated Django model module.
# You'll have to do the following manually to clean this up:
#   * Rearrange models' order
#   * Make sure each model has one field with primary_key=True
#   * Make sure each ForeignKey and OneToOneField has `on_delete` set to the desired behavior
#   * Remove `managed = False` lines if you wish to allow Django to create, modify, and delete the table
# Feel free to rename the models, but don't rename db_table values or field names.
from django.db import models


... just having the model declarations should not require a migration. Haven't checked that myself.

To view this discussion on the web visit https://groups.google.com/d/msgid/django-users/CACwCsY78BT13wTnFH4JtPM9nPxPUZTaw1UJtVG7tsf-Je5QEYA%40mail.gmail.com.


-- 
Signed email is an absolute defence against phishing. This email has
been signed with my private key. If you import my public key you can
automatically decrypt my signature and be sure it came from me. Your
email software can handle signing.
OpenPGP_signature.asc

Larry Martell

unread,
Dec 19, 2023, 8:52:01 AM12/19/23
to django...@googlegroups.com
On Mon, Dec 18, 2023 at 7:23 PM Mike Dewhirst <mi...@dewhirst.com.au> wrote:
>
> On 19/12/2023 9:51 am, Larry Martell wrote:
>
> Hmmm, in my case I do not see any models for those in any of my models.py files. Where would I expect to find them?
>
>
> You have to write them yourself.

Yeah, thanks. I know I can create them myself. I thought you were
saying they were already created by django.
> To view this discussion on the web visit https://groups.google.com/d/msgid/django-users/ace0d1ce-1864-46bd-a9f4-229548eab49f%40dewhirst.com.au.

Larry Martell

unread,
Dec 19, 2023, 2:19:11 PM12/19/23
to django...@googlegroups.com
After creating the models for the m2m tables the changes to them are
not tracked by django-simple history. Could it be that Django is not
using the ORM to update these tables? How could it, since the models
did not exist before I created them today. If the updates are not
through the ORM django-simple history may not be able to see them.

Mike Dewhirst

unread,
Dec 19, 2023, 5:07:11 PM12/19/23
to django...@googlegroups.com
I was saying Django's inspectdb will write them for you.

Larry Martell

unread,
Dec 19, 2023, 6:53:58 PM12/19/23
to django...@googlegroups.com
I got this working. I had to add history = HistoricalRecords(m2m_fields=[products]) to the models with the M2M relationships. Did not see that in the docs anywhere. 

Reply all
Reply to author
Forward
0 new messages