How to deal with Django Cascade deleted objects in django-simple-history?

190 views Asked by At

I have a problem with django-simple-history when I use cascade deletion on objects.

I have several tables in my database that inherit from other tables, so I’ve set the deletion to cascade. The problem is that when I want to query Historical Objects generated by django-simple-history, I do have the one in the parent table, but for objects in the children table, that were automatically deleted by Django, I have this error :

MyApp.models.parentTable_object.DoesNotExist: parentTable_object matching query does not exist.

If I understand the problem, django-simple-history tried to create a Historical object for my deleted object but failed because it needed the parent object it inherited and that no longer exists at this point.

I can’t do without cascading so I hope it’s possible because django-simple-history has met all my expectations so far.

Thanks you for your help

My environment:

  • OS: Windows 10
  • Browser: Firefox
  • Django Simple History Version: 3.1.1
  • Django Version: 4.0.3
  • Database Version: django's integrated SqLite3
1

There are 1 answers

1
DigitalDirk On

Let's see if I understand the problem correctly, this would be an example data model:

class Parent(models.Model):  
    name = models.CharField(max_length=100)
    history = HistoricalRecords()

class Child(models.Model):`
    parent = HistoryForeignKey(Parent, on_delete=models.CASCADE)
    name = models.CharField(max_length=100)
    history = HistoricalRecords()

Please note the HistoricForeignKey link.

When you do delete a Parent instance, you cannot get the child object anymore.

You probably get the DoesNotExist issue when trying to fetch the children like:

Child.history.as_of(time_stamp).get(parent=parent)

If you try to get the Child with the parent ID like:

Child.history.as_of(time_stamp).get(parent_id=parent_id)

In that way you can still get the child through the HistoricalChild table.

Also notice this thread on github get a more clear idea.

In one of the messages this person mentions the issue you are having as well

This also has a benefit of allowing you to know if an instance is derived from history or not, which might be useful as well. I noticed this does not work for chained lookups however, for example if you have a get_object_or_404 that uses a filter like b__c__id it doesn't seem to see "b" in this case. I'm sure with another patch that could be made to work as well.

Up until now this patch has not yet been made.

I hope this helps you, if not, let me know.