【问题标题】:How to handle multiple user types with Django 1.7 user model如何使用 Django 1.7 用户模型处理多种用户类型
【发布时间】:2015-03-23 22:34:14
【问题描述】:

我对 Python 和 Django 非常陌生。我正在尝试为代理、经纪人、公司和客户等不同角色设置用户模型。这些角色中的每一个都可以在站点上注册为用户。然后代理和经纪人可以拥有面向公众的个人资料页面。

我必须使用自定义用户模型还是内置用户模型才能工作?我有其他属性,例如代理和经纪人的许可证、位置、语言、照片等。

class MyUser(AbstractBaseUser):
    AGENTS = 'AG'
    BROKERS = 'BR'
    COMPANY = 'CP'
    CUSTOMER = 'CM'

    ROLE_IN_CHOICES = (
        (AGENTS, 'Agent'),
        (BROKERS, 'Broker'),
        (COMPANY, 'Company'),
        (CUSTOMER, 'Customer'))

    first_name = models.CharField(max_length=100, blank=True)
    second_name = models.CharField(max_length=100, blank=True)
    middle_name = models.CharField(max_length=100, blank=True)
    dob = models.DateField(blank=True, null=True)
    phone = models.CharField(max_length=10)
    secondary_phone = models.CharField(max_length=10, blank=True, null=True)

......

@property
def is_agent(self):
    return self.role in (self.AGENTS)

@property
def is_customer(self):
    return self.role in (self.CUSTOMER)

@property
def is_broker(self):*
    return self.role in (self.BROKER)

@property
def is_company(self):
    return self.role in (self.COMPANY)

....

我可以不使用基本用户模型并实现相同吗?我在写作轨道上吗?

如何为这些角色(代理、经纪人)创建面向公众的页面?

这是我第一次尝试使用 Python 和 Django。我正在使用 Django 1.7.7 和 Python 3.4

【问题讨论】:

    标签: python django


    【解决方案1】:

    您应该改为从 Django User 模型扩展并添加您需要的额外字段:

    from django.contrib.auth.models import User as Auth_User
    
    class User(Auth_User):
    
        # add your extra fields here like roles, etc
        phone = CharField(max_length=20, null=True, blank=True)
    
        # add your extra functions
        def extra_user_function(self):
             return "This is an extra function"
    

    这样你就有了自己的字段和 Django 用户字段...

    迁移后,如果您检查数据库,您将拥有 auth_user 和 your_app_user 表。

    请记住 request.user 只会给你超级字段......为了获得你需要的扩展类

    User.objects.get(id=request.user.id)
    

    如果您不自己添加任何 auth_user,那么最新的将只有额外的字段,并且 它的 id 将与 auth.User 相同

    注意:这很重要!

    否则 request.user.idyour_app.User.id 不匹配,因此 User.objects.get(id=request.user.id) 获胜'不起作用,您必须查询数据库才能找到 your_app.User.id

    User.object.get(user_ptr_id = request.user.id)
    

    其他需要考虑的事项

    这将起作用:

    # you_app.User objects gets vars from auth.User
    user = User.objects.get(id=request.user.id)
    first_name = user.first_name
    

    但这行不通

    # auth.User trying to get a function from your_app.User
    user =  request.user
    user.extra_user_function()
    

    所以用户模型可能是这样的:

    import os
    from django.contrib.auth.models import User as Django_User
    from django.db.models import CharField, ImageField
    
    class User(Django_User):
    
        phone = CharField(max_length=20, null=True, blank=True)
        observations = CharField(max_length=2048, null=True, blank=True)
        picture = ImageField(upload_to='users', default='default/avatar.jpg')
    
        class Meta:
            # adding extra permissions (default are: add_user, change_user, delete_user)
            permissions = (
                ("access_user_list", "Can access user list"),
                ("access_user", "Can access user"),
            )
            ordering = ["-is_staff", "first_name"]
    

    Django 已经有组,而不是在用户上创建角色,所以你应该使用它们。

    各组遵循相同的逻辑:

    from django.contrib.auth.models import Group as Auth_Group
    from django.db import models
    
    class Group(Auth_Group):
    
        observations = models.CharField(max_length=2048, null=True, blank=True)
    
        def get_users_in_group(self):
            return self.user_set.filter(is_active=1).order_by('first_name', 'last_name')
    
        def count_users_in_group(self):
            return self.user_set.count()
    
        def __unicode__(self):
            return self.name
    
        class Meta:
            permissions = (
                 ("access_group_list", "Can access group list"),
                 ("access_group", "Can access group"),
            )
            ordering = ["name"]
    

    您可以清除/添加用户到组:

    user.groups.clear()
    user.groups.add(group)
    

    清除/添加组权限:

    group.permissions.clear()
    group.permissions.add(permission)
    

    还有一个装饰器来检查用户是否有权限

    from django.contrib.auth.decorators import permission_required
    
    @permission_required(("users.change_user","users.access_user",))
    def your_view(request):
         ...
    

    我过去尝试过很多事情,但我想这是要走的路。

    如果您确实需要角色,并且用户可以拥有多个角色,那么最好的办法是创建一个模型角色并将其添加到具有 ManyToMany 字段的用户

    roles = ManyToManyField(Role)
    

    但你可以通过组来做到这一点

    【讨论】:

    • 感谢您的快速回复。扩展 auth_user 与 AbstractBaseUser 有什么区别?我如何将不同类型的用户与这个新模型联系起来?创建不同的用户模型比为所有人创建一个模型更好?
    • 检查 auth.models.py 文件。用户模型扩展了 AbstractModel 但有一个元字段“可交换”。对于我阅读的内容,这允许您将模型替换为自己的模型,但我不确定。至于捆绑不同类型的用户,使用“组”字段并遵循相同的逻辑。您可以从 auth.Group 扩展您的“公司”,为其提供更多字段并设置权限...让我将组添加到答案中...
    • "安装自定义 User 模型将破坏任何扩展 User 的代理模型。代理模型必须基于具体的基类;通过定义自定义 User 模型,您删除了 Django 可靠识别基类。” docs.djangoproject.com/en/dev/topics/auth/customizing/…
    • 我猜你可以毫无问题地使用 AbstractUser,但如果不添加额外的位,AbstractBaseUser 将无法工作。最后,auth.User 和 AbstractUser 完全一样。
    猜你喜欢
    • 2018-08-05
    • 1970-01-01
    • 2015-01-09
    • 1970-01-01
    • 2016-12-19
    • 1970-01-01
    • 2014-08-10
    • 1970-01-01
    • 2018-07-02
    相关资源
    最近更新 更多