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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/16925129/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-19 00:01:13  来源:igfitidea点击:

Generate unique id in django from a model field

pythondjangodjango-models

提问by picomon

I want to generate different/unique id per request in django from models field. I did this but I keep getting the same id.

我想在 django 中从模型字段为每个请求生成不同/唯一的 id。我这样做了,但我一直得到相同的 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

采纳答案by Paulo Bu

UPDATE:If you are using Django 1.8 or superior, @madzohan has the right answer below.

更新:如果您使用的是 Django 1.8 或更高版本,@madzohan 在下面有正确的答案。



Do it like this:

像这样做:

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

The reason why is because with the parenthesis you evaluate the function when the model is importedand this will yield an uuid which will be used for every instance created.

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

Without parenthesis you passed just the function needed to be called to give the default value to the field and it will be called each time the model is imported.

没有括号,您只传递了需要调用的函数来为字段提供默认值,并且每次导入模型时都会调用它。

You can also take this approach:

您也可以采用这种方法:

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

Hope this helps!

希望这可以帮助!

回答by woodardj

This answer from Google Code worked for me:

来自 Google Code 的这个答案对我有用:

https://groups.google.com/d/msg/south-users/dTyajWop-ZM/-AeuLaGKtyEJ

https://groups.google.com/d/msg/south-users/dTyajWop-ZM/-AeuLaGKtyEJ

add:

添加:

from uuid import UUID

from uuid import UUID

to your generated migration file.

到您生成的迁移文件。

回答by madzohan

since version 1.8 Django has UUIDFieldhttps://docs.djangoproject.com/en/1.8/ref/models/fields/#django.db.models.UUIDField

由于版本 1.8 Django 有UUIDFieldhttps://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

回答by shacker

If you need or want to use a custom ID-generating function rather than Django's UUID field, you can use a while loop in the save()method. For sufficiently large unique IDs, this will almost never result in more than a single db call to verify uniqueness:

如果您需要或想要使用自定义 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()