我正在开发Django 1.5中的学校数据库系统,并计划拥有许多不同的用户类型(学生,员工,父),它们是AbstractUser的子类(实际上是AbstractUser的另一个抽象子类)。我只是试图在我的系统中添加一个外部开发的应用程序,它在一些ForeignKey中使用User用于某些模型,但是,由于我的用户类型不是“用户”实例,因此失败了。我不能将应用程序模型设置为使用AbstractUser,因为不能使用外键的抽象类。我当时正在考虑添加到我的settings.py AUTH_USER_MODEL = 'myapp.MyUser'
并使用settings.AUTH_USER_MODEL代替应用中的ForeignKey的User。但是,我有3种不同的用户类型,所以也不能这样做。
早期的原型使用Django 1.4,它不支持自定义用户模型,因此引用了用户,但这需要为每个查询提供额外的连接,这导致了非常复杂的查询。这是我可以继续推进的唯一方法,还是有另一种解决方案?
答案 0 :(得分:3)
我已成功使用以下解决方案:
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
这样您就不需要知道它是哪种类型的用户,只需实现您的逻辑 如果不让我知道,我希望这很清楚!