3

私は Django 1.5 で学校のデータベース システムを開発しており、AbstractUser (実際には、AbstractUser の別の抽象サブクラス) をサブクラス化するさまざまなユーザー タイプ (学生、スタッフ、親) を持つことを計画していました。外部で開発されたアプリを自分のシステムに追加しようとしましたが、そのアプリは一部のモデルで ForeignKey でユーザーを使用していますが、ユーザー タイプが「ユーザー」インスタンスではないため、これは失敗します。外部キーに抽象クラスを使用できないため、AbstractUser を使用するようにアプリ モデルを設定できません。次に、settings.py に追加しAUTH_USER_MODEL = 'myapp.MyUser'、アプリの ForeignKey の User の代わりに settings.AUTH_USER_MODEL を使用することを検討していました。ただし、3 つの異なるユーザー タイプがあるため、これも実行できません。

以前のプロトタイプでは Django 1.4 を使用していましたが、これはカスタム User モデルをサポートしていなかったため、代わりに User への参照がありましたが、これにはクエリごとに追加の結合が必要であり、非常に複雑なクエリにつながっていました。これが私がこれを進める唯一の方法ですか、それとも別の解決策がありますか?

4

1 に答える 1

5

私は次の解決策をうまく使用しました:
1. SchoolUsermodels.py でクラスを作成します - これがあなたの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 ファイルを作成し、そこにユーザー ロジック全体を配置します。他のすべてが継承し、ファクトリ メソッドを実装する 1 つの抽象クラスを用意します。

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 に答える