2010-09-14 118 views
18

我在我的代碼中使用request.user.get_profile()。然而,並非所有用戶都有與其賬戶相關聯的用戶簡檔。有沒有什麼辦法可以在撥打request.user.get_profile()時自動創建用戶配置文件,如果他們沒有一個,而不必更改我的各個request.user.get_profile()調用。也許使用信號或什麼的。Django創建用戶配置文件(如果不存在)

我遇到的問題是我使用單一登錄登錄,所以如果有人登錄另一個系統,然後去我的網站他們登錄但沒有得到一個用戶配置文件創建(我創建一個用戶他們登錄時的個人資料)。

+0

可以請你檢查這太問題http://stackoverflow.com/questions/17806683/create-row -of-date-while-creating-superuser,我面臨的問題,不能上來 – user2086641 2013-07-23 16:58:11

回答

22

通常,用戶配置文件對象是在用戶實例創建後立即創建的。這很容易用信號完成。

The problem I have is that I use a single sign-in login so if someone logs in on another system and then goes to my site they are logged in but don't get a user profile created (I create a user profile when they log in).

顯然在用戶創建時使用信號不適用於您。一種方法來完成你想要做的事情是用自定義函數替換request.user.get_profile()的呼叫。說get_or_create_user_profile(request)。此功能可以嘗試檢索用戶的配置文件,然後在不存在的情況下快速創建一個配置文件。

對於如:

def get_or_create_user_profile(request): 
    profile = None 
    user = request.user 
    try: 
     profile = user.get_profile() 
    except UserProfile.DoesNotExist: 
     profile = UserProfile.objects.create(user, ...) 
    return profile 
+1

謝謝。我喜歡這個答案,但並不熱衷於在我的代碼中更改request.user.get_profile()的所有實例。是否沒有信號可以附加到UserProfile post_get(我不知道這是否存在) – John 2010-09-14 10:15:30

+0

@John:AFAIK沒有內置的信號,它是通過'get'(如你所說的'post_get')發送的。該文檔似乎同意http://docs.djangoproject.com/en/dev/ref/signals/ – 2010-09-14 10:43:37

+0

通過中間件來做什麼呢? – John 2010-09-14 14:33:44

3

我發現這個解決方案,我想在這個網站的使用方法:http://www.turnkeylinux.org/blog/django-profile

User.profile = property(lambda u: UserProfile.objects.get_or_create(user=u)[0]) 

使用像這樣的屬性似乎不是定義一個新的方法更清潔,但我同意通過您的代碼庫並將user.get_profile()引用更改爲user.profile將會很痛苦。

然後,是不是你的全局文件搜索和替換功能是什麼?

+0

通常第一個用戶(超級用戶)不會創建其配置文件,因爲它是在'./manage.py startapp'中創建的。 – hobbes3 2012-03-29 07:40:28

+2

該解決方案的問題在於,每次引用User.profile時,它都會觸發db來檢索配置文件。例如如果你這樣做:User.profile.field =「derp」然後是User.profile.save(),它會從數據庫重新加載.profile文件,並在保存之前丟失所做的更改。重點在於它對性質的不良使用。使用一種方法,而不是那個功能imo – sqwerty 2012-04-22 20:08:27

+0

嗯,我不認爲這是一個不好的使用屬性。不過我會發佈一個改進。 – 2012-05-02 05:20:21

3

上bskinner的答案,並在響應sqwerty的評論大廈,您可以使用此:

def get_or_create_profile(user): 
    """ 
    Return the UserProfile for the given user, creating one if it does not exist. 

    This will also set user.profile to cache the result. 
    """ 
    user.profile, c = UserProfile.objects.get_or_create(user=user) 
    return user.profile 

User.profile = property(get_or_create_profile) 

所以,如果需要的話,這將創建一個配置文件,然後User.profile.field = "deep"作品User.profile.save()

1

修改如下。否則,將顯示「AttributeError:無法設置屬性」。這裏的監護人分配權限是可選的。

 
def get_or_create_profile(user): 
    profile, created = UserProfile.objects.get_or_create(user=user) 
    assign('change_userprofile', user, profile) 
    assign('delete_userprofile', user, profile) 
    return profile 

User.profile = property(get_or_create_profile) 
1

這裏是一個可以用來創建缺少他們誰所有用戶的默認配置文件一個匆匆管理命令。有了這個地方,你可以在任何時候運行./manage.py missing_profiles,或將它添加到cron作業等

from django.core.management.base import BaseCommand 
from django.contrib.auth.models import User 
from people.models import Profile 

''' 
Create default profiles for any User objects that lack them. 
''' 


class Command(BaseCommand): 
    help = "Create default profiles for any User objects that lack them." 

    def handle(self, *args, **options): 
     users = User.objects.filter(profile=None) 
     for u in users: 
      Profile.objects.create(user=u) 
      print("Created profile for {u}".format(u=u)) 
相關問題