2014-06-20 3 views
2

사용자 이름을 고유하게 만드는 논리에 약간의 도움이 필요합니다.django - 사용자의 고유 이름 만들기

저는 장고 사용자 프로필을 가지고 있습니다. 나는이 방법으로 사용자를 만드는 오전 :

fullname = request.POST.get('fullname') 
random_username = ''.join(random.sample(string.ascii_lowercase, 8)) 
new_user = User.objects.create_user(random_username, email, passwort) 
##update siteprofile of this new user 
userprofile = new_user.get_profile() 

""" 
    i need to make this fullname unique with this logic: 
    for example john is the fullname of new user. i need to check if there are 
    other johns in db, if there is another user with this name, i will name the 
    user with 'john1'. if there are 2, the new user will get the name 'john3' 
    how can I check this in db in some efficient way? 

""" 
userprofile.name = fullname 
userprofile.save() 

답변

2

이 있어야합니다

i = 0 
orig_fullname = fullname 
created = False 
while not created: 
    profile, created = UserProfile.objects.get_or_create(name=fullname) 
    if not created: 
     i+=1 
     fullname = orig_fullname + str(i) 
# there you have new user's profile 

주, USERPROFILE 모델에서 해당 필드 '이름': 당신이 양식을 사용하지 않을 경우, 당신은 그런 식으로 작업을 수행 할 수 있습니다 이에 따라 IntegrityError을 저장하고 업데이트하십시오. 이름 존재 여부를 확인하기 위해 쿼리를 수행하면 두 개의 개별 스레드를 검색하여 동시에 동일한 전체 이름을 작성하려고하는 경쟁 조건이 생성됩니다.

from django.db import transaction 

@transaction.commit_manually 
def set_fullname(userprofile, fullname, i=0): 
    new_fullname = u"{}{}".format(fullname, str(i) if i else '') 
    try: 
     userprofile.fullname = new_fullname 
     userprofile.save() 

     transaction.commit() 

     return userprofile 
    except IntegrityError: 
     transaction.rollback() 

     i += 1 
     # Just recursively try until we a valid name. This could be problematic if you 
     # have a TON of users, but in that case you could just the filter before then to see 
     # what number to start from. 
     return set_fullname(userprofile, fullname, i) 

userprofile = set_fullname(userprofile, fullname) 
+0

아주 좋은데, 이것은 세계의 두 부분에서 두 사람이 똑같은 이름을 설정하지 않았는지 확인합니다. – doniyor

+0

맞습니다. 그리고 db 레벨을 수행하므로 두 스레드가 동시에 같은 이름을 설정하는 경우가 거의 없습니다. – sdolan

+0

''userprofile.fullname = fullname''는''userprofile.fullname = new_fullname''이어야합니다, 맞습니까? – doniyor

1

를 이러한 목적을 위해이 양식 https://docs.djangoproject.com/en/dev/topics/forms/를 사용하는 것이 좋을 것이다. 당신이 확인하고 싶은 독특한 = true 매개 변수를 https://docs.djangoproject.com/en/dev/ref/models/fields/#unique

+0

좋은 소리입니다. while-true 나는 최신의 fullname을 갖게 될 것입니다. – doniyor

+0

당신은 그것을 삽입하고 IntegrityError를 잡아서 고유성이 db 레벨에서 처리되도록하고, 경쟁 조건을 피하려고합니다. – sdolan

+0

@doniyor 그냥 답을 던지기가 더 쉬웠다 – sdolan