django-pghistory icon indicating copy to clipboard operation
django-pghistory copied to clipboard

Tracking linked models being assigned/removed

Open dracos opened this issue 4 years ago • 1 comments

This may not be possible, or I may have missed something obvious :) Say I have two models:

@pghistory.track(pghistory.Snapshot('author.snapshot'))
class Author(models.Model):
    name = models.CharField(max_length=100)

@pghistory.track(pghistory.Snapshot('book.snapshot'))
class Book(models.Model):
    title = models.CharField(max_length=100)
    author = models.ForeignKey(Author)

I have Book A by author AA and Book B by author BB. But it turns out Book B was actually written by AA. So I update the data:

>>> book = Book.objects.get(title='B')
>>> book.author = Author.objects.get(name='AA')
>>> book.save()

If I now look at the history of Book B, what I see is what you would expect:

>>> pghistory.models.AggregateEvent.objects.target(Book.objects.get(title='B')).order_by('pgh_created_at').values()
<AggregateEventQuerySet [
  {'pgh_diff': None,                  'pgh_id': 2, 'pgh_label': 'book.snapshot', 'pgh_data': {'id': 2, 'title': 'B', 'author_id': 2}, ... },
  {'pgh_diff': {'author_id': [2, 1]}, 'pgh_id': 3, 'pgh_label': 'book.snapshot', 'pgh_data': {'id': 2, 'title': 'B', 'author_id': 1}, ... }
]>

The history of Author AA, however is as follows:

>>> for i in pghistory.models.AggregateEvent.objects.target(Author.objects.get(name='AA')).order_by('pgh_created_at').values(): print(i)
{'pgh_id': 1, 'pgh_label': 'author.snapshot', 'pgh_data': {'id': 1, 'name': 'AA'}, 'pgh_diff': None, ... }
{'pgh_id': 1, 'pgh_label': 'book.snapshot', 'pgh_data': {'id': 1, 'title': 'A', 'author_id': 1}, 'pgh_diff': None, ... }
{'pgh_id': 3, 'pgh_label': 'book.snapshot', 'pgh_data': {'id': 2, 'title': 'B', 'author_id': 1}, 'pgh_diff': None, ... }

This does make perfect sense from AA's point of view, the Author B entry is new to it and the docs are clear that pgh_diff only shows the difference "between this event and the previous event on the same object with the same label.", but what ideally I would like is for that last row to include a diff like the one in the Book B history, saying the author ID had changed from 2 to 1. That way I can get a history of Author AA, being able to tell the difference between books being added as new entries, and added as transfers from other authors.

Is there a way to do this that I have missed/ haven't thought of?

dracos avatar Jun 11 '21 18:06 dracos

Dunno if this is related or not(!), but I've opened https://github.com/Opus10/django-pghistory/pull/16 which lets target() receive a queryset/list of objects, not only one. I thought this potentially could be used for the above, in that you could call pghistory.models.AggregateEvent.objects.target(author_aa.books.all()) to then get the history of all of them at once, maybe. But even if not useful for this ticket, thought it might be more generically useful anyway.

dracos avatar Jun 12 '21 14:06 dracos

As mentioned in #16 , this was deployed in version 1.4

wesleykendall avatar Sep 06 '22 00:09 wesleykendall