【问题标题】:Django: Customize the User model's return fieldDjango:自定义用户模型的返回字段
【发布时间】:2015-12-11 00:33:52
【问题描述】:

Django 的用户模型的默认返回字段是“用户名”。但是,我的应用程序需要它是“first_name”。 目前,我刚刚 fork Django 并对 User 模型进行了更改:

def __str__(self):
    return self.first_name

它工作正常,但我想知道是否有其他简单的方法可以在不分叉 Django 的情况下做到这一点?

【问题讨论】:

  • 编辑库不是一个合适的解决方案。您应该继承用户模型并在子类中使用 str 函数。

标签: django django-models


【解决方案1】:

有一种方法可以在 User 类上注入新方法。

from django.contrib.auth.models import User

def get_first_name(self):
    return self.first_name

User.add_to_class("__str__", get_first_name)

你可以把它放在common 应用程序中(最好放在models.py 中)

不是很干净,但是如果您只需要这个单一的更改,它就可以在不覆盖整个 User 模型的情况下完成这项工作。

【讨论】:

    【解决方案2】:

    我认为最好的方法是使用custom user model,然后定义get_full_name() 和/或get_short_name() 以返回first_name

    【讨论】:

    • 有些情况您不想在项目中添加自定义用户模型。但仍然是最好的方法。
    【解决方案3】:

    首先,使用django documentation创建自定义用户

    一旦您有了自定义用户,请转到 MyUser 类。添加字段,如 first_name、last_name 或任何您需要的字段。

    你会得到这样的东西。

    class MyUser(AbstractBaseUser):
        email = models.EmailField(
            verbose_name='email address',
            max_length=255,
            unique=True,
        )
        first_name = models.CharField(max_length=32)
        last_name = models.CharField(max_length=32)
        date_of_birth = models.DateField()
        is_active = models.BooleanField(default=True)
        is_admin = models.BooleanField(default=False)
    
        objects = MyUserManager()
    
        USERNAME_FIELD = 'email'
        REQUIRED_FIELDS = ['date_of_birth']
    
        def get_full_name(self):
            # The user is identified by their email address
            return self.email
    
        def get_short_name(self):
            # The user is identified by their email address
            return self.email
    
        def __str__(self):              # __unicode__ on Python 2
            return self.email
    
        def has_perm(self, perm, obj=None):
            "Does the user have a specific permission?"
            # Simplest possible answer: Yes, always
            return True
    
        def has_module_perms(self, app_label):
            "Does the user have permissions to view the app `app_label`?"
            # Simplest possible answer: Yes, always
            return True
    
        @property
        def is_staff(self):
            "Is the user a member of staff?"
            # Simplest possible answer: All admins are staff
            return self.is_admin
    

    现在,将你的类中的 __str__ 函数编辑到这个。

        def __str__(self):              # __unicode__ on Python 2
            return self.first_name
    

    请记住,date_of_birth 等字段是可选的。

    【讨论】:

      【解决方案4】:

      类似于Randy Tang's answer:您可以通过使用Proxy Model 来避免the issue Ramast mentioned

      class MyUser(User):
          class Meta:
              proxy = True
      
          def __str__(self):
              return self.first_name
      

      根据文档:

      您可以创建、删除和更新代理模型的实例以及所有 数据将像您使用原始数据一样保存(非代理) 型号。

      【讨论】:

        【解决方案5】:

        以下解决方案是否有效?

        class MyUser(User):
        
            def __str__(self):
                return self.first_name
        

        不要再使用User,而是使用MyUser

        【讨论】:

        • 遗憾的是,这会创建另一个名为 my_user 的数据库表,其字段与用户模型相同。您存储在 MyUser 对象中的任何值都无法从 User 对象访问,反之亦然
        • 正确。为了不再使用默认的用户模式,你必须这样做:从 django.contrib.auth.models 导入 AbstractUser 然后 class MyUser(AbstractUser)。然后,您可以通过 MyUser 访问 first_name,甚至无需定义它。您也可以从 AbstractBaseUser 继承,但实现起来更复杂。
        • 您还可以将Meta 类中的db_table 属性定义为auth_user,以强制Django 使用与contrib 用户模型相同的数据库表。
        猜你喜欢
        • 2021-04-15
        • 2011-04-08
        • 2017-03-31
        • 2021-12-08
        • 2019-08-01
        • 1970-01-01
        • 1970-01-01
        • 2017-10-21
        • 2013-07-02
        相关资源
        最近更新 更多