mirror of
https://github.com/jazzband/django-auditlog.git
synced 2026-03-16 22:20:26 +00:00
Merge d630437533 into eb9eefd76f
This commit is contained in:
commit
518ac4d6ab
4 changed files with 23 additions and 28 deletions
|
|
@ -2,6 +2,13 @@
|
|||
|
||||
## Next Release
|
||||
|
||||
## (2025-08-14)
|
||||
|
||||
### Fixes
|
||||
|
||||
- fix: Ensure `object_pk` lookup works for non-string primary keys by casting PK to string in `get_for_object()` and related queries.
|
||||
- fix: Updated tests to correctly match log entries for integer, UUID, or string primary keys. ([#746](https://github.com/jazzband/django-auditlog/pull/746))
|
||||
|
||||
#### Improvements
|
||||
|
||||
- feat: Add `AUDITLOG_USE_FK_STRING_REPRESENTATION` setting that controls how foreign key changes are represented ([#779)](https://github.com/jazzband/django-auditlog/pull/779))
|
||||
|
|
|
|||
|
|
@ -4,6 +4,7 @@ from django import urls as urlresolvers
|
|||
from django.conf import settings
|
||||
from django.contrib import admin
|
||||
from django.contrib.admin.views.main import PAGE_VAR
|
||||
from django.contrib.contenttypes.models import ContentType
|
||||
from django.core.exceptions import PermissionDenied
|
||||
from django.http import HttpRequest
|
||||
from django.template.response import TemplateResponse
|
||||
|
|
@ -139,9 +140,11 @@ class AuditlogHistoryAdminMixin:
|
|||
obj = self.get_object(request, unquote(object_id))
|
||||
if not self.has_view_permission(request, obj):
|
||||
raise PermissionDenied
|
||||
|
||||
ct = ContentType.objects.get_for_model(obj.__class__)
|
||||
log_entries = (
|
||||
LogEntry.objects.get_for_object(obj)
|
||||
LogEntry.objects.filter(
|
||||
content_type=ct, object_pk=str(obj.pk)
|
||||
) # <--- Fixed here
|
||||
.select_related("actor")
|
||||
.order_by("-timestamp")
|
||||
)
|
||||
|
|
|
|||
|
|
@ -148,10 +148,7 @@ class LogEntryManager(models.Manager):
|
|||
content_type = ContentType.objects.get_for_model(instance.__class__)
|
||||
pk = self._get_pk_value(instance)
|
||||
|
||||
if isinstance(pk, int):
|
||||
return self.filter(content_type=content_type, object_id=pk)
|
||||
else:
|
||||
return self.filter(content_type=content_type, object_pk=smart_str(pk))
|
||||
return self.filter(content_type=content_type, object_pk=smart_str(pk))
|
||||
|
||||
def get_for_objects(self, queryset):
|
||||
"""
|
||||
|
|
@ -160,8 +157,7 @@ class LogEntryManager(models.Manager):
|
|||
:param queryset: The queryset to get the log entries for.
|
||||
:type queryset: QuerySet
|
||||
:return: The LogEntry objects for the objects in the given queryset.
|
||||
:rtype: QuerySet
|
||||
"""
|
||||
:rtype: QuerySet"""
|
||||
if not isinstance(queryset, QuerySet) or queryset.count() == 0:
|
||||
return self.none()
|
||||
|
||||
|
|
@ -170,25 +166,14 @@ class LogEntryManager(models.Manager):
|
|||
queryset.values_list(queryset.model._meta.pk.name, flat=True)
|
||||
)
|
||||
|
||||
if isinstance(primary_keys[0], int):
|
||||
return (
|
||||
self.filter(content_type=content_type)
|
||||
.filter(Q(object_id__in=primary_keys))
|
||||
.distinct()
|
||||
)
|
||||
elif isinstance(queryset.model._meta.pk, models.UUIDField):
|
||||
primary_keys = [smart_str(pk) for pk in primary_keys]
|
||||
return (
|
||||
self.filter(content_type=content_type)
|
||||
.filter(Q(object_pk__in=primary_keys))
|
||||
.distinct()
|
||||
)
|
||||
else:
|
||||
return (
|
||||
self.filter(content_type=content_type)
|
||||
.filter(Q(object_pk__in=primary_keys))
|
||||
.distinct()
|
||||
)
|
||||
# Always compare as strings for PostgreSQL compatibility
|
||||
primary_keys = [smart_str(pk) for pk in primary_keys]
|
||||
|
||||
return (
|
||||
self.filter(content_type=content_type)
|
||||
.filter(Q(object_pk__in=primary_keys))
|
||||
.distinct()
|
||||
)
|
||||
|
||||
def get_for_model(self, model):
|
||||
"""
|
||||
|
|
|
|||
|
|
@ -191,7 +191,7 @@ class SimpleModelTest(TestCase):
|
|||
self.delete(obj)
|
||||
|
||||
# Check for log entries
|
||||
qs = LogEntry.objects.filter(content_type=content_type, object_pk=pk)
|
||||
qs = LogEntry.objects.filter(content_type=content_type, object_pk=str(pk))
|
||||
self.assertEqual(qs.count(), 1, msg="There is one log entry for 'DELETE'")
|
||||
|
||||
history = qs.get()
|
||||
|
|
|
|||
Loading…
Reference in a new issue