【问题标题】:Django user profileDjango 用户配置文件
【发布时间】:2023-03-29 13:10:02
【问题描述】:

向用户个人资料添加其他字段(例如位置、性别、雇主等)时,我是否应该向django.contrib.auth.models.User 添加其他列并将其保存在那里?还是我应该创建一个新表来保存用户个人资料信息?

另外,当用户上传个人资料图片时,我应该将其保存在同一个表格中吗? (请注意,这不是生产服务器,我只是在本地运行服务器上执行此操作以解决问题)。谢谢

【问题讨论】:

标签: django django-models


【解决方案1】:

您必须为用户个人资料制作模型:

class UserProfile(models.Model):  
    user = models.ForeignKey(User, unique=True)
    location = models.CharField(max_length=140)  
    gender = models.CharField(max_length=140)  
    employer = models.ForeignKey(Employer)
    profile_picture = models.ImageField(upload_to='thumbpath', blank=True)

    def __unicode__(self):
        return u'Profile of user: %s' % self.user.username

然后在settings.py中配置:

AUTH_PROFILE_MODULE = 'accounts.UserProfile'

【讨论】:

  • 谢谢,这对我有用。但是我将如何访问 admin.py 中的用户字段?我正在尝试为 UserProfile 设置 ModelAdmin,并尝试访问这样的用户字段:'user__last_name'。但我收到此错误:“user__last_name”不是可调用的,也不是“UserAdmin”的属性,也不是在模型“UserProfile”中找到的。如何访问这些元素?
  • 或许值得一提的是,在这种情况下,与用户的 OneToOne 比 ForeignKey(unique=True) 方法更好。
  • -1 用于使用 ForeignKey 而不是 OneToOne,@Dmitry 有更好的答案。 AUTH_PROFILE_MODULE 也是 Django 1.5+ 不需要的旧设置
  • AUTH_PROFILE_MODULE 已弃用。
  • 我可以知道class UserProfile 应该在哪个文件中定义?目前,我们的class MyUser(AbstractBaseUser) 定义在文件models.py 中。 UserProfile 应该放在同一个文件中吗?
【解决方案2】:

从概念上讲,OneToOneField 类似于具有 unique=True 的 ForeignKey,但关系的“反向”端将直接返回单个对象。这是扩展 User 类的推荐方式。

class UserProfile(models.Model):  
    user = models.OneToOneField(User)
    ...

【讨论】:

  • 非常干净的解决方案
【解决方案3】:

当前的 Django 是 1.9,这里是对已接受的过时答案的一些更新

  1. 使用models.OneToOneField(User)
  2. 添加related_name='profile'
  3. 在 Python 3 中使用 .__str__().format()

像这样

class UserProfile(models.Model):  
    user = models.OneToOneField(User, related_name='profile')
    location = models.CharField(max_length=140)  
    gender = models.CharField(max_length=140)  
    ...

    def __str__(self):
        return 'Profile of user: {}'.format(self.user.username)

使用related_name,您可以轻松访问用户的个人资料,例如request.user

request.user.profile.location
request.user.profile.gender

无需额外查找。

【讨论】:

  • 它可以工作,但是当我登录到我的 Django 管理员时,它显示错误用户没有个人资料。我的功能正常工作,但我无法访问我的管理面板
【解决方案4】:

Django 提供了storing additional information about users in a separate table 的方式(称为用户配置文件)。

【讨论】:

    【解决方案5】:

    从 Django 1.5 开始,您可以使用简单的设置条目将默认用户替换为您的自定义用户对象:

    AUTH_USER_MODEL = 'myapp.MyUser'
    

    如需了解更多详情,请查看Django documentation entry

    【讨论】:

    • 每个人都应该注意“auth”部分。 Avatars 和 bios 不应该在 AUTH_USER_MODEL 中。除非您想将 kerberos 之类的东西集成到您的用户身份验证中,否则我会坚持使用 django.contrib.auth。在 Django 1.5+ 中,与用户的一对一模型应该仍然是做事的方式。似乎位置、性别、雇主不是有效的身份验证参数,不应添加到自定义用户模型中。
    • 赞成链接到官方(和目前)当前的文档。我很欣赏这一点,因为这是其中一个问题,看起来互联网存储关于框架的曾经很好的答案的历史的巨大容量导致了混乱的大杂烩。 :)
    • @JohnLockwood 刚刚重新更新了链接,所以它在未来几年应该会很好:P
    【解决方案6】:

    我找到了一个解决方案here。基本上你只是扩展默认形式UserCreationForm,但保持相同的名称。它与 Django 文档告诉您的方式无缝协作UserProfiles

    【讨论】:

      【解决方案7】:

      可以更新答案以添加信号接收器,如果配置文件不存在则创建配置文件,如果配置文件已经存在则更新。

      @receiver(post_save, sender=User)
      def create_or_update_user_profile(sender, instance, created, **kwargs):
          if created:
              Profile.objects.create(user=instance)
          instance.profile.save()
      

      https://simpleisbetterthancomplex.com/tutorial/2016/11/23/how-to-add-user-profile-to-django-admin.html 帖子还包括如何在管理面板中编辑、列出自定义配置文件。

      【讨论】:

        【解决方案8】:

        如果您想从用户对象中获取用户配置文件数据。

        from django.contrib.auth.models import User
        request.user.profile
        

        【讨论】:

          【解决方案9】:

          当前的 2 个热门答案已过时

          如果您直接引用User(例如,通过在外键中引用它),您的代码将无法在AUTH_USER_MODEL 设置已更改为不同用户模型的项目中运行。 [..] 当您定义外键或与用户模型的多对多关系时,不要直接引用User [..],您应该使用 AUTH_USER_MODEL 设置来指定自定义模型。

          from django.conf import settings
          from django.db import models
          
          class UserProfile(models.Model):
              user = models.OneToOneField(
                  settings.AUTH_USER_MODEL,
                  on_delete=models.CASCADE,
                  related_name="userprofile",
              )
          

          https://docs.djangoproject.com/en/3.2/topics/auth/customizing/#referencing-the-user-model

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 2012-08-01
            • 2014-04-29
            • 2012-03-27
            • 2012-03-11
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多