【问题标题】:Django create userprofile if does not exist如果不存在,Django 创建用户配置文件
【发布时间】:2010-09-14 08:59:56
【问题描述】:

我在代码中的很多地方都使用了request.user.get_profile()。但是,并非所有用户都有与其帐户相关联的用户配置文件。有没有什么方法可以在调用request.user.get_profile() 时自动创建用户配置文件,如果他们没有,而无需更改我的每个request.user.get_profile() 调用。也许使用信号或其他东西。

我遇到的问题是我使用单点登录登录,所以如果有人在另一个系统上登录然后访问我的网站,他们已经登录但没有创建用户配置文件(我创建了一个用户配置文件当他们登录时)。

【问题讨论】:

标签: django


【解决方案1】:

通常用户配置文件对象是在创建用户实例之后立即创建的。使用信号很容易做到这一点。

我遇到的问题是我使用单点登录,所以如果有人在另一个系统上登录然后访问我的网站,他们已经登录但没有创建用户配置文件(我创建了一个用户配置文件当他们登录时)。

显然在创建用户时使用信号对您不起作用。完成您尝试做的事情的一种方法是用自定义函数替换对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

【讨论】:

  • 谢谢。我喜欢这个答案,但并不热衷于在我的代码中更改 request.user.get_profile() 的所有实例。有没有我可以附加到 UserProfile post_get 的信号(我不知道这是否存在)
  • @John:AFAIK 没有在get 上发送的内置信号(如您所说的post_get)。文档似乎同意docs.djangoproject.com/en/dev/ref/signals
  • 通过中间件怎么办?
  • @John:是的,既然你提到了它,我想有可能拦截一个请求并创建一个用户配置文件。警告:我从来没有尝试过类似的东西。
  • @ManojGovindan,您能否在创建用户时检查这个 SO 问题stackoverflow.com/questions/17806683/… 在数据库中创建表数据。
【解决方案2】:

我在这个网站上找到了我喜欢使用的解决方案: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 引用会很痛苦。

话说回来,这不就是你的全局文件搜索和替换功能的用途吗?

【讨论】:

  • 通常第一个用户(超级用户)不会创建其个人资料,因为它是在./manage.py startapp 期间创建的。
  • 此解决方案的问题是,每次您引用 User.profile 时,它​​都会访问数据库以检索配置文件。例如如果您执行以下操作:User.profile.field = "derp" 然后 User.profile.save(),它将从数据库重新加载 .profile 并在保存之前丢失您的更改。关键是它对属性的使用不好。使用一种方法代替该功能 imo
  • 嗯,我不认为这是对属性的不好使用。不过我会发布一个改进。
【解决方案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() 工作。

【讨论】:

    【解决方案4】:

    修改如下。否则,将显示“AttributeError: can't set attribute”。监护人分配权限在这里是可选的。

    def get_or_create_profile(用户): 配置文件,创建 = UserProfile.objects.get_or_create(user=user) 分配('change_userprofile',用户,个人资料) 分配('delete_userprofile',用户,个人资料) 返回资料 User.profile = property(get_or_create_profile)

    【讨论】:

      【解决方案5】:

      这是一个快速管理命令,可用于为缺少默认配置文件的任何用户创建默认配置文件。有了这个,您可以随时运行./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))
      

      【讨论】:

        猜你喜欢
        • 2012-07-14
        • 1970-01-01
        • 1970-01-01
        • 2019-05-23
        • 2020-07-23
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-08-05
        相关资源
        最近更新 更多