2013-06-04 13 views
23

Chcę wygenerować inny/unikalny identyfikator dla każdego żądania w django z pola modeli. Zrobiłem to, ale wciąż otrzymuję ten sam identyfikator.Generowanie unikalnego identyfikatora w django z pola modelu

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 

Odpowiedz

35

UPDATE: Jeśli używasz Django 1.8 lub wyższy, @madzohan ma właściwą odpowiedź poniżej.


Czy to tak:

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

Powodem jest dlatego z nawiasem ty ocenić funkcję kiedy model jest importowany a to przyniesie to UUID, który będzie używany dla każdego Utworzono instancję.

Bez nawiasów przekazano tylko funkcję wymagającą wywołania w celu podania wartości domyślnej dla pola i będzie ona wywoływana za każdym razem, gdy importowany jest model.

Można także wziąć tego podejścia:

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 

nadzieję, że to pomaga!

+0

zrobiłem that..I'm teraz coraz NULL w moim DB, oznacza to, że nie oszczędza! Czy mogę opublikować moje opinie? – picomon

+1

Jeśli masz wartość domyślną, nie będziesz potrzebować "null = True" w definicji pola. Usuwam odpowiedź. Spróbuj bez tego. –

+0

Teraz otrzymuję ten błąd IntegrityError w/pay/ (1048, "Kolumna" eyw_transactionref "nie może być pusta") Usunąłem puste = True również. – picomon

58

od wersji 1.8 Django ma 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 
+8

To jest rzeczywista odpowiedź, jeśli masz Django1.8 + :) –

+0

potrzebujesz również 'unique = True'? – Sevenearths

+0

@Sevenearths http://stackoverflow.com/questions/31499836/does-djangos-new-uuidfields-default-attribute-take-care-of-the-university – madzohan

8

Jeśli potrzebujesz lub chcesz użyć funkcji niestandardowej ID generowania zamiast pola UUID Django, można użyć pętli while w metodzie save(). Dla dostatecznie dużych unikalnych identyfikatorów, to prawie nigdy nie powodują więcej niż jednego połączenia db celu zweryfikowania niepowtarzalności:

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() 
Powiązane problemy