Search code examples
djangomanytomanyfieldm2mdjango-reversion

django-reversion revert ManyToMany fields outside admin


I am using django-reversion in my project. And it works good except one thing: I can't get previous versions of ManyToMany fields. But in django admin it is works, not in my code. To get previous version I use following code:

vprod = Version.objects.get_for_date(product, ondate).get_object_version().object

and it works except m2m field where 'product' is object of Product class,

class Product(models.Model):
    name = models.CharField(max_length=255)
    elements = models.ManyToManyField(Sku)

class Sku(models.Model):
    name = models.CharField(max_length=255, verbose_name="SKU Name")

I can get vprod.name and it returns what I need, but when I try vprod.elements.all() it returns list only the current (last) version, even if the number of elements changed.


Solution

  • If I understand it correctly, I think you should get the revision for the version; the version contains the data of the object, the revision contains versions for multiple objects. Have a look at:

    some_version.revision.version_set.all()
    

    Concretely, I think you should use (untested):

    [
        v for v in Version.objects.get_for_date(product, ondate) \
            .revision.version_set.all()
        if version.content_type == ContentType.objects.get_for_model(Sku)
    ]
    

    Note, btw, that reversions should know that it should follow relationships. Using the low level API:

    reversion.register(YourModel, follow=["your_foreign_key_field"])