如果 Django-reversion 中没有任何变化,请不要创建新版本
Don't create new version if nothing has changed in Django-reversion
我只想在 django-reversion 中发生更改时才保存新的对象版本。我浏览了文档,但没有找到任何相关信息。我怎样才能实现它?
您可以使用 the ignore_duplicates
option。不幸的是
It doesn't follow
relations, as that can get expensive and slow very quickly.
如果你真的想忽略跟随关系的重复项,你有两种可能:
- 分叉并禁用限制
这里删除and explicit
https://github.com/etianen/django-reversion/blob/master/reversion/revisions.py#L199
默认设置ignore_duplicates
为True
https://github.com/etianen/django-reversion/blob/master/reversion/revisions.py#L368
小心,如上所述,它可能会很慢。
- 收听the post revision commit signal并手动删除重复版本
设置ignore_duplicates
为False
并添加信号接收器:
from django.db import transaction
from django.dispatch import receiver
from reversion.models import Revision, Version
from reversion.signals import post_revision_commit
def clear_versions(versions, revision):
count = 0
for version in versions:
previous_version = Version.objects.filter(
object_id=version.object_id,
content_type_id=version.content_type_id,
db=version.db,
id__lt=version.id,
).first()
if not previous_version:
continue
if previous_version._local_field_dict == version._local_field_dict:
version.delete()
count += 1
if len(versions_ids) == count:
revision.delete()
@receiver(post_revision_commit)
def post_revision_commit_receiver(sender, revision, versions, **kwargs):
transaction.on_commit(lambda: clear_versions(versions, revision))
它也可能很慢,但您可以异步执行(例如,在 Celery 任务中):
# tasks.py
@celery.task(time_limit=60, ignore_result=True)
def clear_versions(revision_id, versions_ids):
count = 0
if versions_ids:
for version in Version.objects.filter(id__in=versions_ids):
previous_version = Version.objects.filter(
object_id=version.object_id,
content_type_id=version.content_type_id,
db=version.db,
id__lt=version.id,
).first()
if not previous_version:
continue
if previous_version._local_field_dict == version._local_field_dict:
version.delete()
count += 1
if len(versions_ids) == count:
Revision.objects.only('id').get(id=revision_id).delete()
# signals.py
@receiver(post_revision_commit)
def post_revision_commit_receiver(sender, revision, versions, **kwargs):
transaction.on_commit(
lambda: clear_versions.delay(revision.id, [v.id for v in versions])
)
我只想在 django-reversion 中发生更改时才保存新的对象版本。我浏览了文档,但没有找到任何相关信息。我怎样才能实现它?
您可以使用 the ignore_duplicates
option。不幸的是
It doesn't follow relations, as that can get expensive and slow very quickly.
如果你真的想忽略跟随关系的重复项,你有两种可能:
- 分叉并禁用限制
这里删除and explicit
https://github.com/etianen/django-reversion/blob/master/reversion/revisions.py#L199
默认设置ignore_duplicates
为True
https://github.com/etianen/django-reversion/blob/master/reversion/revisions.py#L368
小心,如上所述,它可能会很慢。
- 收听the post revision commit signal并手动删除重复版本
设置ignore_duplicates
为False
并添加信号接收器:
from django.db import transaction
from django.dispatch import receiver
from reversion.models import Revision, Version
from reversion.signals import post_revision_commit
def clear_versions(versions, revision):
count = 0
for version in versions:
previous_version = Version.objects.filter(
object_id=version.object_id,
content_type_id=version.content_type_id,
db=version.db,
id__lt=version.id,
).first()
if not previous_version:
continue
if previous_version._local_field_dict == version._local_field_dict:
version.delete()
count += 1
if len(versions_ids) == count:
revision.delete()
@receiver(post_revision_commit)
def post_revision_commit_receiver(sender, revision, versions, **kwargs):
transaction.on_commit(lambda: clear_versions(versions, revision))
它也可能很慢,但您可以异步执行(例如,在 Celery 任务中):
# tasks.py
@celery.task(time_limit=60, ignore_result=True)
def clear_versions(revision_id, versions_ids):
count = 0
if versions_ids:
for version in Version.objects.filter(id__in=versions_ids):
previous_version = Version.objects.filter(
object_id=version.object_id,
content_type_id=version.content_type_id,
db=version.db,
id__lt=version.id,
).first()
if not previous_version:
continue
if previous_version._local_field_dict == version._local_field_dict:
version.delete()
count += 1
if len(versions_ids) == count:
Revision.objects.only('id').get(id=revision_id).delete()
# signals.py
@receiver(post_revision_commit)
def post_revision_commit_receiver(sender, revision, versions, **kwargs):
transaction.on_commit(
lambda: clear_versions.delay(revision.id, [v.id for v in versions])
)