如何在TastyPie的水合物循环中使用Django F()表达式?

时间:2013-08-08 03:10:10

标签: python django tastypie race-condition

我有一个版本号的模型。我希望它在使用现有的id通过TastyPie发布新数据时自我增量。我目前正在通过水合物方法这样做,只要两个用户不尝试一次更新,该方法就有效:

class MyResource(ModelResource):
    ...
    def hydrate_version(self, bundle):
        if 'id' in bundle.data:
            target = self._meta.queryset.get(id=int(bundle.data['id']))
            bundle.data['version'] = target.version+1
        return bundle

我希望通过使用Django's F() expressions更强大地执行此操作,例如:

    def hydrate_version(self, bundle):
        if 'id' in bundle.data:
            from django.db.models import F
            target = self._meta.queryset.get(id=int(bundle.data['id']))
            bundle.data['version'] = F('version')+1
        return bundle

然而,这给了我一个错误:

TypeError: int() argument must be a string or a number, not 'ExpressionNode'

有没有办法通过TastyPie更强大地增加版本号?

谢谢!

2 个答案:

答案 0 :(得分:1)

我会覆盖Django Model的save()方法,并在那里执行更新。无论来自tastypie还是来自django / python shell的更新,这都具有确保相同行为的附加优势。

def save(self, *args, **kwargs):
    self.version = F('version') + 1

    super(MyModel, self).save(*args, **kwargs)

答案 1 :(得分:0)

这已在github here得到解答,但我自己还没试过。引用该链接:

  

您在水合物方法中设置了bundle.data。通常你在hydrate方法中修改bundle.obj,在脱水方法中修改bundle.data。

     

此外,这些F对象应用于Django模型字段。

     

我认为你想要的是:

def hydrate_version(self, bundle):
    if bundle.obj.id is not None:
        from django.db.models import F
        bundle.obj.version = F('version')+1
    return bundle