2013-06-04 8 views
23

Tôi muốn tạo id khác nhau/duy nhất cho mỗi yêu cầu trong django từ trường mô hình. Tôi đã làm điều này nhưng tôi tiếp tục nhận được cùng một id.Tạo id duy nhất trong django từ trường mô hình

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 

Trả lời

35

UPDATE: Nếu bạn đang sử dụng Django 1.8 hoặc cao, @madzohan có câu trả lời đúng dưới đây.


Làm điều đó như thế này:

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

Lý do tại sao là bởi vì với ngoặc bạn đánh giá chức năng khi mô hình được nhập khẩu và điều này sẽ mang lại một uuid mà sẽ được sử dụng cho tất cả các ví dụ được tạo.

Nếu không có dấu ngoặc đơn, bạn chỉ cần truyền hàm để gọi giá trị mặc định cho trường và nó sẽ được gọi mỗi lần nhập mô hình.

Bạn cũng có thể áp dụng cách này:

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!

+0

Tôi đã làm điều đó. Tôi có nên đăng các quan điểm của mình không? – picomon

+1

Nếu bạn có một giá trị mặc định thì bạn sẽ không cần 'null = True' trong định nghĩa trường. Tôi sẽ xóa khỏi câu trả lời. Hãy thử mà không có điều đó. –

+0

Bây giờ nhận được lỗi này IntegrityError tại/trả tiền/ (1048, "Cột 'eyw_transactionref' không thể null") Tôi loại bỏ trống = True cũng. – picomon

58

kể từ phiên bản 1.8 Django có 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

Đây là câu trả lời thực tế nếu bạn có Django1.8 + :) –

+0

bạn có cần 'unique = True' không? – Sevenearths

+0

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

8

Nếu bạn cần hoặc muốn sử dụng một chức năng tùy chỉnh ID-tạo chứ không phải là lĩnh vực UUID của Django, bạn có thể sử dụng một vòng lặp while trong phương pháp save(). Đối với các ID duy nhất đủ lớn, điều này hầu như không bao giờ dẫn đến nhiều hơn một lệnh gọi db duy nhất để xác minh tính duy nhất:

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