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.Ch开发者_运维百科arField(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.
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"])
I had the same issue and thanks to @Webthusiast's answer I got my working code. Adapting to your example would be something like this.
Imports:
from django.contrib.contenttypes.models import ContentType
import reversion
Register your models:
reversion.register(Sku)
reversion.register(Product, follow=['elements'])
And then you can iterate:
object = Product.objects.get(some_id)
versions = reversion.get_for_object(self.object)
for version in versions:
elements = [v.object_version.object \
for v in version.revision.version_set.all() \
if v.content_type == ContentType.objects.get_for_model(Product)]
The documentation for this is now on Read the Docs. Refer to the 'Advanced model registration' section of the Low-level API page.
精彩评论