如何为多个模型提供连续ID?

时间:2017-05-03 15:51:29

标签: python django database django-models models

我编写了自己的结算软件,但我不知道如何解决这个问题。

现在我有3个型号:

数 收据 MilageReceipt

关键是我需要给我的客户写两种收据。但是对于财政部来说,他们必须持续不断地识别他们。所以Number只包含一个自动字段,而Receipt和MilageReceipt只有一个外键。这样我就有两个不同模型的ID。

但现在我想扩展它以处理多家公司。因此,有两种不同类型的收据需要连续数字,但会有多个用户都需要自己的连续数字。

我希望得到一些结果: 收据:公司:1,身份证:1 收据:公司:2,身份证:1 收据:公司:1,身份证:2 MilageReceipt:公司:1,身份证:3 收据:公司:2,身份证:2 MilageReceipt:公司:1,身份证:4 收据:公司:1,身份证号码:5 MilageReceipt:公司:2,id:3

我希望我想要实现的目标有些明确。你能否指点我如何设置模型以获得这种行为?

我希望尽可能保持管理员的原创性,所以我想在模型级别上执行此操作,而不是视图 - 如果可能的话。例如,现在,每次创建Receipt或MilageReceipt时,我都会自动创建数字。所以用户甚至没有注意到。

感谢您的帮助!

1 个答案:

答案 0 :(得分:0)

对于连续序列,您实际上无法使用数据库序列。最简单的解决方案是拥有自己的表(Model)来保存序列。这是我用来做的一些代码:

import numpy as np
from sklearn import decomposition

demo_df = pd.read_csv('data.csv')
pca = decomposition.PCA(n_components=4)

comps = pca.fit(demo_df).transform(demo_df)

np.savetxt('data_reduced.csv', comps, delimiter=',')

要获得下一个序列,您将形成一个命名序列的键字符串,例如:

class Sequence(models.Model):

    class Meta:
        verbose_name = 'Sequence'
        permissions = (('view_sequence', 'Can View Sequence'),)

    name = models.CharField(max_length=20)
    value = models.IntegerField()

    def __str__(self):
        return 'Sequence %s=%s' % (self.name, self.value)

    def __unicode__(self):
        return self.__str__()

    @classmethod
    def set(cls, name, value=None, increment=0):
        with transaction.atomic():
            seq = cls.objects.select_for_update().filter(name=name).first()
            if not seq:
                seq = cls(name=name, value=0)

            seq.value = increment + (value if value is not None else seq.value)
            seq.save()
        return seq.value

    @classmethod
    def get_next(cls, name):
        return cls.set(name, increment=1)

由于每家公司都有不同的密钥,因此它们将是不同的密钥。

如果您使用此功能,请说出您的收据保存方法,如下所示:

nextnumber = Sequence.get_next('receipt_%d' % company.pk)

每当您保存收据时,如果它没有seq_num,则会为其分配一个。

这里只有一个问题,即交易代码的结构方式,如果出现问题,可以跳过一个数字。为避免这种情况,请将transaction.atomic()块移动到收据save()方法中。