djangodjango-simple-history

Filtering Django Simple-History by created/creator


I've created a simple Django data model that is using Django Simple-History for auditing:

from django.db import models

from simple_history.models import HistoricalRecords


class AuditedModel(models.Model):
    history = HistoricalRecords(inherit=True)

In the interest of DRY, I'm trying to leverage Simple-History's history_date & history_user attributes in place of adding created_at and created_by attributes. I've added a couple of properties to simplify accessing the history for these attributes as follows:

    @property
    def created_date(self):
        return self.history.earliest().history_date

    @property
    def created_by(self):
        return self.history.earliest().history_user

This works fine when I'm working with an instance. Now, I'm running into issues when I try to filter querysets by history_date or history_user. For example, I can filter for objects created in the last 24hrs by doing this:

queryset = AuditedModel.objects.all()

queryset.filter(
    uuid__in=AuditedModel.history.annotate(
        created_date=Min('history_date'),
    ).filter(
        created_date__gte=timezone.now() - relativedelta(days=1)
    ).values_list(
        'uuid', flat=True
    )
)

But, I'm unable to figure out how to filter the AuditedModel by more than one attribute. Ultimately, I'd like to get a queryset with new instances that were created by a specific user.

Something like:

queryset.filter(
    uuid__in=AuditedModel.history.annotate(
        created_date=Min('history_date'),
    ).filter(
        created_date__gte=timezone.now() - relativedelta(days=1)
    ).values_list(
        'uuid', flat=True
    ),
    history__history_user=request.user
)

This doesn't work as history can't be resolved, but it illustrates (I hope) what I'm trying to get at.

Has anyone out there used Simple History in this way, and could they maybe give me a push in the right direction to resolve this? At this point, I'm debating replacing my created_by and created_at properties with proper fields as I can't see an alternative but that feels wrong.


Solution

  • Of course, I realised how simple it was shortly after posting my question to StackOverflow.

    In case anyone want to see what worked for me:

    queryset.filter(
        uuid__in=AuditedModel.history.annotate(
            created_date=Min('history_date'),
        ).filter(
            created_date__gte=timezone.now() - relativedelta(days=1),
            history_user=request.user  # Filter by user here!
        ).values_list(
            'uuid', flat=True
        )
    )