从模型字段在django中生成唯一ID

pic*_*mon 39 python django django-models

我想在模型字段的django中为每个请求生成不同/唯一的id.我做了这个,但我一直得到同样的身份.

class Paid(models.Model):
     user=models.ForeignKey(User)
     eyw_transactionref=models.CharField(max_length=100, null=True, blank=True, unique=True, default=uuid.uuid4()) #want to generate new unique id from this field

     def __unicode__(self):
        return self.user
Run Code Online (Sandbox Code Playgroud)

mad*_*han 101

从版本1.8开始,Django有UUIDField https://docs.djangoproject.com/en/1.8/ref/models/fields/#django.db.models.UUIDField

import uuid
from django.db import models

class MyUUIDModel(models.Model):
    id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
    # other fields
Run Code Online (Sandbox Code Playgroud)

  • 如果你有Django1.8 + :),这是真正的答案 (15认同)
  • @Sevenearths http://stackoverflow.com/questions/31499836/does-djangos-new-uuidfields-default-attribute-take-care-of-the-uniqueness (2认同)

Pau*_* Bu 51

更新:如果您使用的是Django 1.8或更高版本,@ madzohan的答案如下.


像这样做:

#note the uuid without parenthesis
eyw_transactionref=models.CharField(max_length=100, blank=True, unique=True, default=uuid.uuid4)
Run Code Online (Sandbox Code Playgroud)

原因是因为使用括号在导入模型时评估函数,这将产生一个uuid,它将用于创建的每个实例.

如果没有括号,则只传递需要调用的函数,以便为字段提供默认值,并且每次导入模型时都会调用它.

你也可以采用这种方法:

class Paid(models.Model):
     user=models.ForeignKey(User)
     eyw_transactionref=models.CharField(max_length=100, null=True, blank=True, unique=True)

     def __init__(self):
         super(Paid, self).__init__()
         self.eyw_transactionref = str(uuid.uuid4())

     def __unicode__(self):
        return self.user
Run Code Online (Sandbox Code Playgroud)

希望这可以帮助!

  • 如果您有默认值,则在字段定义中不需要“null=True”。我将从答案中删除。尝试没有那个。 (2认同)

sha*_*ker 11

如果您需要或想要使用自定义ID生成函数而不是Django的UUID字段,则可以在save()方法中使用while循环.对于足够大的唯一ID,这几乎不会导致多个db调用以验证唯一性:

urlhash = models.CharField(max_length=6, null=True, blank=True, unique=True)

# Sample of an ID generator - could be any string/number generator
# For a 6-char field, this one yields 2.1 billion unique IDs
def id_generator(size=6, chars=string.ascii_uppercase + string.digits):
    return ''.join(random.choice(chars) for _ in range(size))

def save(self):
    if not self.urlhash:
        # Generate ID once, then check the db. If exists, keep trying.
        self.urlhash = id_generator()
        while MyModel.objects.filter(urlhash=self.urlhash).exists():
            self.urlhash = id_generator()
    super(MyModel, self).save()
Run Code Online (Sandbox Code Playgroud)