如何在 Django 中创建自动递增整数字段?

Posted

技术标签:

【中文标题】如何在 Django 中创建自动递增整数字段?【英文标题】:How do I make an auto increment integer field in Django? 【发布时间】:2014-02-03 10:03:13 【问题描述】:

我正在为购物车制作Order 模型,我需要创建一个在下订单时自动递增的字段:

class Order(models.Model):
    cart = models.ForeignKey(Cart)
    add_date = models.DateTimeField(auto_now_add=True)
    order_number = models.IntegerField()
    enable = models.BooleanField(default=True)

如何使IntegerField 自动递增?

【问题讨论】:

默认会有一个自增id字段。 使用pre_save信号检测购物车的变化?你的订单是什么? 【参考方案1】:

在 Django 中

1 : Django 模型类具有名称为 id 的默认字段,即自动递增字段。 2:您可以使用@987654321@ 定义自己的自动增量字段 字段。

类订单(模型。模型): auto_increment_id = models.AutoField(primary_key=True) # primary_key = True 如果你不想使用 django 给你的模型的默认字段“id”

数据库设计

+------------+------------------------------------ -------------------------------------------------- -------------------------------------------------- ------------------------------------+ |表 |创建表 | +------------+------------------------------------ -------------------------------------------------- -------------------------------------------------- ------------------------------------+ |核心订单 |创建表`core_order`( `auto_increment_id` int(11) NOT NULL AUTO_INCREMENT, 主键(`auto_increment_id`) ) 引擎=InnoDB 默认字符集=latin1 | +------------+------------------------------------ -------------------------------------------------- -------------------------------------------------- ------------------------------------+ 一组中的 1 行(0.01 秒)

如果你想使用 django 的默认 id 作为增量字段。

类订单(模型。模型): add_date = models.DateTimeField(auto_now_add=True)

数据库设计

+--------------+------------------------------------ -------------------------------------------------- -------------------------------------------------- --------------------------+ |表 |创建表 | +--------------+------------------------------------ -------------------------------------------------- -------------------------------------------------- --------------------------+ |核心订单 |创建表`core_order`( `id` int(11) NOT NULL AUTO_INCREMENT, `add_date` 日期时间不为空, 主键(`id`) ) 引擎=InnoDB 默认字符集=latin1 | +--------------+------------------------------------ -------------------------------------------------- -------------------------------------------------- --------------------------+

【讨论】:

整数字段需要这个。 另外请注意,您不能拥有多个 AutoField,并且 Django 默认为 id 字段使用一个,因此如果您需要同时记录 id 表示主键的自动递增整数字段(例如,在用于保留数据插入顺序的Through 模型中),此解决方案不起作用。 AutoField 在每个模型多次使用时不起作用。我得到:A model can't have more than one AutoField >AutoFields 必须设置 primary_key=True。【参考方案2】:

在每个模型的 django 中,您将获得默认的 id 字段,即自动递增。但是,如果您手动要使用自动增量。您只需要在您的模型中指定AutoField

class Author(models.Model):
    author_id = models.AutoField(primary_key=True)

您可以在Django Documentation for AutoField 中阅读有关 django 中 auto 字段的更多信息

【讨论】:

【参考方案3】:
class Belly(models.Model):
    belly_id = models.AutoField(primary_key=True)
    belly_name = models.CharField(max_length=50)

******** 或 *******

class Belly(models.Model):
   belly_name = models.CharField(max_length=50)

区别在于:

第一个表具有主键belly_id(指定为AutoField),第二个表具有主键id(隐式)。

我觉得没必要直接用这个; 如果您不指定,主键字段将自动添加到您的模型中。否则 查看Django Documentation for AutoField 了解与AutoField 相关的更多详细信息。

【讨论】:

【参考方案4】:

您可以创建一个自动字段。这是相同的documentation

请记住,Django 不允许在一个模型中拥有多个 AutoField,在您的模型中,您已经有一个作为主键(这是默认设置)。因此,您必须重写模型的保存方法,并且可能会从表中获取最后插入的记录,并相应地增加计数器并添加新记录。

请确保该代码线程安全,因为如果出现多个请求,您最终可能会尝试为不同的新记录插入相同的值。

【讨论】:

【参考方案5】:

已编辑:修复了在数据库中没有 YourModel 条目时停止工作的代码错误。

很多地方都提到了应该如何使用 AutoField,当然,在可能的情况下应该使用它。

但是,您自己实现自动递增字段是有正当理由的(例如,如果您需要一个从 500 开始的 id 或出于任何原因以十为单位递增)。

在你的models.py

from django.db import models

def from_500():
    '''
    Returns the next default value for the `ones` field,
    starts from 500
    '''
    # Retrieve a list of `YourModel` instances, sort them by
    # the `ones` field and get the largest entry
    largest = YourModel.objects.all().order_by('ones').last()
    if not largest:
        # largest is `None` if `YourModel` has no instances
        # in which case we return the start value of 500
        return 500
    # If an instance of `YourModel` is returned, we get it's
    # `ones` attribute and increment it by 1
    return largest.ones + 1

def add_ten():
    ''' Returns the next default value for the `tens` field'''
    # Retrieve a list of `YourModel` instances, sort them by
    # the `tens` field and get the largest entry
    largest = YourModel.objects.all().order_by('tens').last()
    if not largest:
        # largest is `None` if `YourModel` has no instances
        # in which case we return the start value of 10
        return 10
    # If an instance of `YourModel` is returned, we get it's
    # `tens` attribute and increment it by 10
    return largest.tens + 10


class YourModel(model.Model):
    ones = models.IntegerField(primary_key=True,
                               default=from_500)
    tens = models.IntegerField(default=add_ten)

【讨论】:

我们如何在 YourModel 声明之前引用它? @SubTain Malik 在这里是可能的,因为 YourModel 继承自 django 的 model.Model。在应用程序启动时,Django 首先加载模型类,使其能够工作【参考方案6】:

我需要的东西:具有固定整数数量的文档编号,也可以像 AutoField 一样工作。

我的搜索带我走遍了包括。这个页面。

最后我做了这样的事情:

我创建了一个带有DocuNumber 字段的表作为带有foll 的IntegerField。属性:

max_length=6 primary_key=True unique=True default=100000

max_length 可以根据需要为任何值(因此对应的default= 值)。

创建上述模型时发出警告,我可以忽略。

之后,按预期创建了一个文档(虚拟),该文档的整数字段值为 100000。

随后将模型键字段更改为:

将字段类型更改为:AutoField 摆脱了max_lengthdefaultattributes 保留primary_key = True 属性

创建的下一个(所需文档)的值为 100001,后续数字递增 1。

到目前为止一切顺利。

【讨论】:

好吧,我认为一旦你重置你的索引,这将打破【参考方案7】:

您可以覆盖 Django 保存方法official doc about it。

修改后的代码:

class Order(models.Model):
    cart = models.ForeignKey(Cart)
    add_date = models.DateTimeField(auto_now_add=True)
    order_number = models.IntegerField(default=0)  # changed here
    enable = models.BooleanField(default=True)

    def save(self, *args, **kwargs):
        self.order_number = self.order_number + 1
        super().save(*args, **kwargs)  # Call the "real" save() method.

另一种方法是使用信号。更多:

    official Django docs about pre-save *** example about using pre-save signal

【讨论】:

我认为这行不通,它将始终为 1,我想您应该查询设置最后一个 order_number 并根据该数字递增它【参考方案8】:

您可以使用自动递增的默认主键 (id)。

注意:当您使用第一个设计时,即使用默认字段(id)作为主键,通过提及列名来初始化对象。 例如

class User(models.Model):
    user_name = models.CharField(max_length = 100)

然后初始化,

user = User(user_name="XYZ")

如果按照以下方式初始化,

user = User("XYZ")

然后 python 将尝试设置 id = "XYZ" 这会给你的数据类型错误。

【讨论】:

以上是关于如何在 Django 中创建自动递增整数字段?的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 PostgreSQL 在 DBeaver 中创建自动递增/SERIAL id 列?

如何在 PHPMyAdmin 中使 MySql 中的字段自动递增?

如何在django创建模板中创建对象时自动插入当前用户?

如何使用 EF 核心在 SQLite 中创建自动增量列?

如何使用 EF 核心在 SQLite 中创建自动增量列?

如何在模型 Django 中创建密码字段