Django non primary_key AutoField

Moj*_*imi 5 python django django-models

我们正在迁移并对我们的Oracle数据库进行必要的更改,一个主要的变化是我们将UUIDField所有模型(隐藏到客户端)和(尝试添加)定期添加为primary_key AutoField.

我们发现直接向我们的客户端显示primary_key并不是一个好的设计,但他们还要求显示一个ID字段来更容易地引用对象,但Django限制了这一点,因为不允许AutoField不是primary_key

这个问题有解决方法吗?

Tin*_*boy 7

我认为可以使用的是IntegerField(几乎AutoField在引擎盖下使用),并在模型的第一次保存(在它放入数据库之前)中增加它.

我写了一个示例模型来显示如下.

from django.db import models

class MyModel(models.Model):

    # This is what you would increment on save
    # Default this to one as a starting point
    display_id = models.IntegerField(default=1)

    # Rest of your model data

    def save(self, *args, **kwargs):
        # This means that the model isn't saved to the database yet
        if self._state.adding:
            # Get the maximum display_id value from the database
            last_id = self.objects.all().aggregate(largest=models.Max('display_id'))['largest']

            # aggregate can return None! Check it first.
            # If it isn't none, just use the last ID specified (which should be the greatest) and add one to it
            if last_id is not None:
                self.display_id = last_id + 1

        super(MyModel, self).save(*args, **kwargs)
Run Code Online (Sandbox Code Playgroud)

从理论上讲,这只是复制了AutoField一个不同的模型领域.

  • @Tinfoilboy 这不是最好的方法,因为在以下条件下不起作用。1. 如果您同时添加两个项目,并且是在一个事务中完成的,您最终会看到两个项目看到相同的 Max 并获得相同的数字。2. 如果您删除了最后一个项目,那么下一个项目的编号将相同(这可能是您需要的,也可能不是您需要的) 3. 对整个表执行聚合请求非常浪费。更好的解决方案是创建一个专用的 Counter 模型,或者查看 DBMS 的本机序列支持(如果有)。 (2认同)