Django Reversion

时间:2014-11-11 06:27:10

标签: python django django-reversion

我想撤消上一次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")        

我做错了什么?

1 个答案:

答案 0 :(得分: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

UPDATE2

  

我是否可以仅还原已更新(PUT)或任何更改的更改   POST / DELETE请求也可以恢复?

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

  

如何恢复到第n级? [-1]是否意味着DB   恢复到最新的更新?

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

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

UPDATE3

  

如果最初,则值为3并且更新为12然后   恢复到3.值12会发生什么?另外,我怎么样   恢复插入(POST)查询,例如: - 如果我插入12然后我   想要恢复这种变化吗?

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

因此,当您需要还原某个版本时,django-reversion从数据库加载相应的版本模型,反序列化模型数据,并重新保存旧数据。在重新保存期间,如果没有调用方法保存,则当前状态将丢失。如果它被调用,状态将以适当的版本存储(参见上面的文本)。

如果您需要还原刚刚创建的对象,则应手动将其删除。