2010-09-14 74 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)) 
相关问题