在一个查询的其他字段中使用self.id

时间:2012-01-23 00:17:32

标签: django save

不可否认,这是我之前提出的this one非常相似的问题,然而,对它有一个答案会非常好。

我想通过使用主键来填充另一个字段来创建实例。 Yuji Tomita使用两个查询提出了一个解决方案(顺便说一句,它工作得非常好),但我想知道是否可以只使用一个查询来实现这一点。

Yuji Tomita的解决方案:

def save(self, *args, **kwargs):
    add = not self.pk
    super(MyModel, self).save(*args, **kwargs)
    if add:
        self.identification = str(self.id)
        kwargs['force_insert'] = False # create() uses this, which causes error.
        super(MyModel, self).save(*args, **kwargs)

提前致谢。

1 个答案:

答案 0 :(得分:0)

如果主键是自动递增的整数,则可以通过从db shell运行SELECT MAX(id) FROM myTable来计算下一个键;或者在django:

from django.db.models import Max
next_key = MyTable.objects.aggregate(next=Max('id'))['next']+1

这种方法的问题是你必须实现行锁定;否则另一个进程可能会添加到数据库中 - 获取下一个ID值,这将导致您的代码提供IntegrityError异常;并且它无法解决您的“两个查询”挑战。

更好的解决方案是使用非顺序主键。这通常是UUID。在MySQL中,您可以使用UUID()函数作为主键。这可以(合理地)保证不会发生冲突并且是唯一的。

在Django中,没有官方支持UUID字段(已提交patch),但您可以使用lots of examples

如果你走这条路线,那么你可以随时生成主键,然后将其分配给模型而不执行查询。