0

我想撤消上一次 POST/PUt/DELETE 或数据库中的任何类型的事务。我阅读了Django-reversion并尝试实现它。但没有运气。这是我的代码。请确认我做错了什么!!!

要反转的模型:-

@reversion.register
class Shipment(models.Model):
    job_id = models.CharField(max_length = 255)
    time = models.DateTimeField( auto_now_add = True, db_index = True)

@reversion.register
class ShipmentScanMapping(models.Model):
    arm_id = models.CharField(max_length = 255)
    status = models.CharField(max_length = 255)
    barcode = models.CharField(max_length = 255)
    reference_number = models.CharField(max_length = 255)
    customer_name = models.CharField(max_length = 255)
    shipment = models.ForeignKey('Shipment',related_name ='scans')
    time = models.DateTimeField( auto_now_add = True)

意见

@csrf_exempt
@reversion.create_revision()
def db_commit(request):

    arm_id = scan_status = barcode = reference_number = customer_name = job_id = 12
    if request.is_ajax():
        shipment_obj = Shipment(job_id = job_id)
        shipment_obj.save()

        ShipmentScanMapping.objects.create(arm_id = arm_id,status = scan_status,barcode = barcode,reference_number = reference_number,
                                                customer_name = customer_name ,shipment= shipment_obj)

        return HttpResponse(json.dumps('Success'), content_type = "application/json")        

@csrf_exempt
def db_undo(request):
    job_id = 12 # just for demo purpose
    shipment_obj = Shipment.objects.filter(job_id = job_id).order_by('-time')[0]

    your_model = ShipmentScanMapping.objects.get(shipment = shipment_obj)
    version_list = reversion.get_unique_for_object(your_model)[0]
    #version_data = version_list.field_dict
    #print version_data
    version_list.revert()

    return HttpResponse(json.dumps('Success'), content_type = "application/json")        

我在做什么错??

4

1 回答 1

1

在您的示例中,您只需创建新对象。在这种情况下django-reversion,为此对象创建初始状态恢复,但django-reversion允许您回滚到任何先前修订的状态。所以修改你的ShipmentScanMapping对象,然后再试一次。

更新

初始化数据:

>>> import reversion
>>> with reversion.create_revision():
...     shipment_obj = Shipment(job_id = 12)
...     shipment_obj.save()
...
>>> reversion.get_unique_for_object(shipment_obj)
[<Version: Shipment object>]
>>> with reversion.create_revision():
...     your_model = ShipmentScanMapping.objects.create(arm_id = 12,status = 12,barcode = 12,reference_number = 12,customer_name =12,shipment=shipment_obj)
...
>>> reversion.get_unique_for_object(your_model)
[<Version: ShipmentScanMapping object>]
>>> your_model.arm_id
12
>>> your_model.id
1

更新数据:

>>> with reversion.create_revision():
...     your_model.arm_id=15
...     your_model.save()
...
>>> reversion.get_unique_for_object(your_model)
[<Version: ShipmentScanMapping object>, <Version: ShipmentScanMapping object>]
>>> ShipmentScanMapping.objects.get(id=1).arm_id
15
>>> [r.field_dict.get('arm_id') for r in reversion.get_unique_for_object(your_model)]
[u'15', u'12']

恢复:

>>> rev = reversion.get_unique_for_object(your_model)[-1]
>>> rev.field_dict.get('arm_id')
u'12'
>>> rev.revert()
>>> ShipmentScanMapping.objects.get(id=1).arm_id

更新2

我可以只还原那些已更新(PUT)的更改,或者任何 POST/DELETE 请求也可以还原吗?

您还可以恢复已删除的对象,请参阅文档

我怎样才能恢复到第n级?[-1] 是否意味着数据库将恢复到最新更新?

get_unique_for_object方法返回所有以前版本的列表,首先是最新版本。所以你可以像往常一样从 python 的列表中选择。顺便说一句,您可以找到给定日期的最新版本:

rev = reversion.get_for_date(your_model, datetime.datetime(2008, 7, 10))

更新3

如果最初,该值为 3,并更新为 12,然后恢复为 3。值 12 会发生什么?另外,我将如何恢复插入(POST)查询,例如: - 如果我插入 12 然后我想恢复此更改?

好的,让我们考虑一下它是如何工作的。当您注册您的模型时,django-reversion开始观察post_save模型的信号。每当您保存对模型的更改时,都会使用 Django 序列化框架将其序列化为 JSON 字符串,并将其作为reversion.models.Version模型保存到数据库中。

所以当你需要恢复某个版本时,django-reversion从数据库中加载合适的版本模型,反序列化模型数据,并重新保存旧数据。在重新保存期间,如果不调用方法 save,当前状态将丢失。如果它被调用,状态将存储在适当的版本中(见上文)。

如果您需要恢复刚刚创建的对象,您应该手动删除它。

于 2014-11-11T08:39:47.390 回答