Django non primary_key AutoField

时间:2016-12-19 17:34:50

标签: python django django-models

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

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

此问题是否有解决方法?

3 个答案:

答案 0 :(得分:6)

我认为可以使用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)

理论上,这只是复制AutoField所做的事情,只是使用不同的模型字段。

答案 1 :(得分:0)

您还可以将计数用作自动增量。在我的项目中,我像这样使用。

def ids():
    no = Employee.objects.count()
    if no == None:
        return 1
    else:
        return no + 1
emp_id = models.IntegerField(('Code'), default=ids, unique=True, editable=False)

答案 2 :(得分:0)

假设所选DBMS中不支持序列,则解决方案是创建模型:

class Counter(models.Model):
    count = models.PositiveIntegerField(default=0)

    @classmethod
    def get_next(cls):
        with transaction.atomic():
            cls.objects.update(count=models.F('count') + 1)
            return cls.objects.values_list('count', flat=True)[0]

并在数据迁移中创建它的一个实例。如果您正在使用事务管理,这可能会产生一些影响,但是(几乎)可以保证始终返回下一个数字,而不管事务开始时有多少个对象以及是否删除了任何对象。