Подтвердить что ты не робот

Создать уникальный идентификатор в django из поля модели

Я хочу генерировать разные/уникальные id для запроса в django из поля модели. Я сделал это, но я продолжаю получать одинаковый идентификатор.

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
4b9b3361

Ответ 1

ОБНОВЛЕНИЕ: Если вы используете Django 1.8 или выше, @madzohan имеет правильный ответ ниже.


Сделайте это так:

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

Причина в том, что в скобках вы оцениваете функцию при импортировании модели, и это даст 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

Надеюсь, это поможет!

Ответ 3

Если вам нужно или хотите использовать пользовательскую функцию генерации ID, а не поле UUID Django, вы можете использовать цикл while в методе save(). Для достаточно больших уникальных идентификаторов это почти никогда не приведет к более чем одному вызову 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()