UUID作为pk在Django覆盖模型



事情是这样的。当这样做时,它工作了:

class UUIDField(CharField):
    def __init__(self, *args, **kwargs):
        kwargs['max_length'] = kwargs.get('max_length', 22 )
        # kwargs['blank'] = True
        kwargs['default'] = lambda: uuid.uuid1().bytes.encode('base64').rstrip('=n').replace('/', '_')
        CharField.__init__(self, *args, **kwargs)
class UUIDModel(models.Model):
    uuid = UUIDField(primary_key=True, max_length=22, editable=False)

你可以理解,其余的模型继承了UUIDModel,每个人从此过上了幸福的生活。问题是,内置的Django迁移工具(以及South)不能很好地与lambdas兼容。以下是我对尝试绕过lambda的看法:

class UUIDField(CharField):
    def _gen_uuid(self):
      return uuid.uuid1().bytes.encode('base64').rstrip('=n').replace('/', '_')
    def __init__(self, *args, **kwargs):
        kwargs['max_length'] = kwargs.get('max_length', 22 )
        # kwargs['blank'] = True
        kwargs['default'] = self._gen_uuid()
        CharField.__init__(self, *args, **kwargs)

看起来是合法的,但现在模型被覆盖了,也就是说UUID没有改变,每个新模型都被写入相同的pk。因此,我不能创建任何东西的多个实例。我哪里做错了?lambda做了什么,我的代码没有?最重要的是,如何解决这个问题?

@pavel_form的注释帮助我理解了问题的根源。忽略可调用对象似乎修复了:

class UUIDField(CharField):
    def _gen_uuid(self):
      return uuid.uuid1().bytes.encode('base64').rstrip('=n').replace('/', '_')
    def __init__(self, *args, **kwargs):
        kwargs['max_length'] = kwargs.get('max_length', 22 )
        # kwargs['blank'] = True
        kwargs['default'] = self._gen_uuid
        CharField.__init__(self, *args, **kwargs)

尽管如此,它仍然会在迁移中引起相当多的问题。南迁移错误:name 'UUID'未定义(由@pavel-form建议)更进一步,省略了特殊UUIDFIeld的定义,并且被认为可以很好地与迁移一起工作。我会朝那个方向看。

最新更新