Django如何为模型属性自动生成唯一的数字/字符串?

6

我试图在 Django 模型中生成一个 10 位的唯一随机数,而不将其作为主键。我的模型如下:

Class Transaction(models.Model):
      Referrence_Number = models.Charfield(max_lenght = 10, blank=True, editable=False, unique=True) 

我知道Django内置了特殊功能,可以生成随机字符串。这是我在阅读文档后了解到的。

from django.utils.crypto import get_random_string
get_random_string(10).lower()

但是我的问题是如何将这个get_random_string函数应用到我的Django事务模型中,以便在我的Transaction_number实例中使用。我对Django还很陌生,不知道该怎么做。


1
有什么理由不使用 get_random_string 作为字段默认值生成器,就像 Django 文档中 这个部分 中所讨论的那样? - RishiG
我了解到get_random_string生成12位作为默认值,我选择10位数字以便可以索引并通过参考编号搜索对象。我在Django方面是新手。 - Kaustav Sengupta
4个回答

13

我通常使用uuid,创建对象时将uuid字符串设置为字段

the_field = models.CharField(max_length=36, default=uuid.uuid4)

5
您可以将属性的默认值设置为一个生成所需 Referrence_Number 的函数。只要不在记录创建时设置 Referrence_Number 即可。
例如,您的模型属性如下:
from utils import create_new_ref_number

Class Transaction(models.Model):
      Referrence_Number = models.Charfield(
           max_length = 10,
           blank=True,
           editable=False,
           unique=True,
           default=create_new_ref_number
      )

而在你的utils.py文件中,你可能会有如下内容:

import random

def create_new_ref_number():
      return str(random.randint(1000000000, 9999999999))

虽然你可以简单地将 randint 函数放在 default 参数中,但你应该将其抽象化,以便执行额外的细节操作,例如验证是否存在具有相同 id 的记录等。


3
如果create_new_ref_number意外返回一个之前生成过的号码,会发生什么?模型会再次调用默认函数还是会抛出错误? - Kamran Hosseini
1
它也创建了非唯一数字!并导致错误。 - Naazneen Jatu
CharField 打错字了。 - Hardik Gajjar
1
另外,您必须删除 create_new_ref_number 后面的括号,即:default=create_new_ref_number,。否则,在导入模块时,它将在类定义时被调用,生成一个常量值。 - Masood Khaari
1
@MasoodKhaari 是的 - Rubel

4

这将自动创建一个唯一的引用编号(Referrence_Number)

import random

class Transaction(models.Model):
    Referrence_Number = models.Charfield(
            max_length = 10,
            blank=True,
            editable=False,
            unique=True,
            default=create_new_ref_number
        )

    def create_new_ref_number():
                not_unique = True
                while not_unique:
                    unique_ref = random.randint(1000000000, 9999999999)
                    if not Transaction.objects.filter(Referrence_Number=unique_ref):
                        not_unique = False
                return str(unique_ref)

-1
也许你可以在模型上重写save()方法。像这样:
def save(self,*args, **kwargs):
    self.Reference_Number = get_random_string(10).lower()
    super(Transaction, self).save(*args, **kwargs)

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接