2015-02-09 4 views
2

Есть ли способ проверить, существует ли значение в модели при присвоении ей значения по умолчанию? Если присваиваемое значение существует (оно не уникально), затем генерируйте другое значение. (Читать комментарии):Django unique random как значение по умолчанию

def unique_rand(): 
    return ... # Generate a random string with 8 characters length 
       # It shouldn't exists among other persons 
       # If exists then generate another random string 


class Person(models.Model): 
    code = models.CharField(max_length=8, unique=True, default=unique_rand()) 

Может быть, обходной путь не может быть внутри unique_rand, но где-то внутри Person класса. Я не хочу переопределять save метод, потому что мне нужен code до save. Кроме того, я не хочу использовать uuid randoms.

ответ

2

Просто проверьте наличие сгенерированного кода в цикле.

from django.contrib.auth.models import User 

def unique_rand(): 
    while True: 
     code = password = User.objects.make_random_password(length=8) 
     if not Person.objects.filter(code=code).exists(): 
      return code 

class Person(models.Model): 
    code = models.CharField(max_length=8, unique=True, default=unique_rand) 

Обратите внимание, что нет круглых скобок в default=unique_rand аргумента.

Если вы хотите ограничить количество попыток затем изменить цикл от while к for:

def unique_rand(): 
    for _ in range(5): 
     ... 
    raise ValueError('Too many attempts to generate the code') 
+0

Обратите внимание, что @catavaran изменилось 'по умолчанию = unique_rand()' в 'умолчанию = unique_rand'. Это было сделано так, чтобы функция 'unique_rand()' вызывалась каждый раз, когда вы создаете объект Person. В противном случае его можно было бы назвать только один раз - при инициализации модели. –

+0

Должно быть, проблема с расой! Представьте себе: p1 = Person(); p2 = Person() 'then' p1.code' может быть таким же, как 'p2.code', потому что они еще не сохранены. Как насчет этой ситуации?! – deepmax

+0

Тогда исключение 'IntegrityError' будет поднято. Вы все равно не можете этого избежать. – catavaran

Смежные вопросы