web-dev-qa-db-fra.com

Générer un identifiant unique dans Django à partir d'un champ de modèle

Je veux générer un identifiant différent/unique par demande dans Django à partir du champ des modèles. Je l'ai fait mais j'obtiens toujours le même identifiant.

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
38
picomon

MISE À JOUR: Si vous utilisez Django 1.8 ou supérieur, @madzohan a la bonne réponse ci-dessous.


Fais-le comme ça:

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

La raison en est qu'avec la parenthèse vous évaluez la fonction lorsque le modèle est importé et cela produira un uuid qui sera utilisé pour chaque instance créée.

Sans parenthèses, vous avez transmis uniquement la fonction à appeler pour donner la valeur par défaut au champ et elle sera appelée à chaque importation du modèle.

Vous pouvez également adopter cette approche:

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

J'espère que cela t'aides!

50
Paulo Bu

depuis la version 1.8 Django a 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
92
madzohan

Si vous avez besoin ou souhaitez utiliser une fonction de génération d'ID personnalisée plutôt que le champ UUID de Django, vous pouvez utiliser une boucle while dans la méthode save(). Pour les identifiants uniques suffisamment grands, cela n'entraînera presque jamais plus d'un seul appel db pour vérifier l'unicité:

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()
10
shacker

Cette réponse de Google Code a fonctionné pour moi:

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

ajouter:

from uuid import UUID

dans votre fichier de migration généré.

1
woodardj