首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Django非primary_key AutoField

Django非primary_key AutoField
EN

Stack Overflow用户
提问于 2016-12-20 01:34:50
回答 3查看 10.4K关注 0票数 10

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

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

是否有解决此问题的方法?

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2016-12-20 04:30:31

我认为可行的方法是使用IntegerField (与AutoField在幕后使用的差不多),并在模型第一次保存时(在将其放入数据库之前)递增该值。

我在下面写了一个示例模型来展示这一点。

代码语言:javascript
复制
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所做的事情,只是使用了不同的模型字段。

票数 14
EN

Stack Overflow用户

发布于 2019-01-11 22:55:53

假设所选的DBMS中没有序列支持,一个解决方案是创建一个模型:

代码语言:javascript
复制
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]

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

票数 3
EN

Stack Overflow用户

发布于 2018-11-13 17:26:36

您也可以使用count作为自动增量。在我的项目中,我是这样使用的。

代码语言:javascript
复制
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
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/41228034

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档