`log_actions()` changes in v5 - new interface is unclear

log_action() is now deprecated in v5

The new interface is (from test):

LogEntry.objects.log_actions(
    self.user.pk,
    queryset,
    DELETION,
    change_message=msg,
)

I notice that the second param is queryset, which is presumably returns the objects that have been deleted. However, this can only work if the queryset is generated before the objects are deleted. Should this be made clear in the documentation?

I am currently refactoring the django-import-export implementation, and have hit this issue. It worked previously because we had a queryset which retained the objects before deletion.

I’m curious - where is this documented now? I did some digging through the docs and I can’t seem to find anything regarding these methods.

The ticket related to this, #34462 (Deletions in admin panel create N + 1 queries) – Django, identifies that this change will be made, but that’s all I can find.

The change creates an issue for us on the django-import-export project.

We are processing objects line by line, and deleting if required, like this (pseudo code):

for obj in queryset:
  if self.for_delete(obj):
    obj.delete()

LogEntry.objects.log_actions(
    self.user.pk,
    queryset,
    DELETION
)

The issue we have is that

  1. We can’t know which objects will be deleted until the qs is iterated.

  2. We can’t call log_actions() with a ‘deletion’ queryset because the objects will no longer exist.

It worked prior to v5 because we kept a reference to the queryset and could iterate over each result of the import and determine whether it was a create, update or delete.

[Moving this to the Django Internals category for more visibility to the right people.]

@nessita and/or @felixxm - Care to jump in here?

The deprecated methods and new methods are a part of private API so they’re not documented. You can always collect objects before deleting, e.g.

deleted_objects = []

for obj in queryset:
  if self.for_delete(obj):
    deleted_objects.append(obj)
    obj.delete()

LogEntry.objects.log_actions(
    self.user.pk,
    deleted_objects,
    DELETION
)

OK, thanks for clarifying

However, presumably this won’t work because log_actions() now expects a queryset, but we would be supplying a list of objects?

If you look at the sources in django.contrib.admin.models, it appears that the only real requirement is that it be an iterable. I don’t see anything giving me any indication that it requires an actual queryset.

Thanks Ken, I’ll try that. The param name is queryset which could be misleading, maybe others will hit the same issue as they address the deprecation.