3

我正在用 Django 1.5 开发一个学校数据库系统,并计划拥有许多不同的用户类型(学生、员工、家长),这些用户类型是 AbstractUser 的子类(实际上是 AbstractUser 的另一个抽象子类)。我只是试图将一个外部开发的应用程序添加到我的系统中,该应用程序在其某些模型中使用外键中的用户,但是,由于我的用户类型不是“用户”实例,因此失败了。我无法将应用程序模型设置为使用 AbstractUser,因为不能将抽象类用于外键。然后我正在考虑添加到我的 settings.pyAUTH_USER_MODEL = 'myapp.MyUser'并使用 settings.AUTH_USER_MODEL 代替 User 作为应用程序中的 ForeignKey。但是,我有 3 种不同的用户类型,所以也不能这样做。

早期的原型使用 Django 1.4,它不支持自定义 User 模型,因此有一个对 User 的引用,但这需要对每个查询进行额外的连接,这导致了相当复杂的查询。这是我可以继续前进的唯一方法,还是有其他解决方案?

4

1 回答 1

5

我已成功使用以下解决方案:
1. 在 models.py 中创建SchoolUser类 - 这将是您的AUTH_USER_MODEL

TYPES = (('Student', 'Student'), ('Staff', 'Staff'), ('Parent', 'Parent'), )
class SchoolUser(AbstractUser):
    type = models.CharField(max_length=10, choices=TYPES, default='Student')

2. 创建 users.py 文件并将整个用户逻辑放在那里。拥有一个所有其他人都继承自并实现工厂方法的抽象类:

class UserManager(object):
    def __init__(self, user):
        self.user = user

    @classmethod
    def factory(cls, user):
        """
        Dynamically creates user object
        """
        if cls.__name__.startswith(user.type):  # Children class naming convention is important
            return cls(user)
        for sub_cls in cls.__subclasses__():
            result = sub_cls.factory(user)
            if result is not None:
                return result

示例子类(也转到 users.py 文件):

class StudentUser(UserManager):
    def do_something(self):
        pass
class StaffUser(UserManager):
    def do_something(self):
        pass
class ParentUser(UserManager):
    def do_something(self):
        pass

视图是魔法发生的地方;)

def my_view(request):
    school_user = UserManager.factory(request.user)
    if school_user.do_something:  # each class can have different behaviour

这样您就不需要知道它是哪种类型的用户,只需实现您的逻辑即可。
我希望这足够清楚,如果不让我知道!

于 2013-05-22T10:59:52.230 回答