Django のデフォルト認証システム (django.contrib.auth) を使用しています。Django 管理者が操作できるように、ユーザーに「ロール」を追加したいと考えています。
例:
- ユーザーは、スタッフ、教師、生徒、および/または親になることができます
- ユーザーにロールが割り当てられている場合、ユーザーは権限を取得します (たとえば、スタッフメンバーは Django 管理者にサインインできます) 。
- 一部のロールには追加のフィールドがある場合があります (たとえば、親は少なくとも 1 人の生徒と関係があり、各生徒はクラスグループのフィールドを持っています)。
- すべてのロールに追加のフィールドがあるわけではありません
- 保護者は教師またはスタッフになることができ、その逆も可能です
- 学生は別の役割を持つことはできません
モデル内で上記を達成するためのあらゆる種類の (従来の) 方法があります。Django はそれらの多くをサポートしていますが、Django 管理者はサポートしていません。Django admin には多くの優れた機能があるので、それを使用したいと思います (しかし、それが不可能になるのではないかとますます恐れています)。
最初に考えたのは次のモデルです。
class ExtendedUser(contrib.auth.models.User):
"""
For the ease of use I inherit from User. I might
want to add methods later
"""
pass
class StaffMember(models.Model):
"""
A staffmember is a co-worker of the organisation
and has permissions to make changes to (parts of)
the system.
For now the staffmember only has methods
"""
user = models.OneToOneField(ExtendedUser, related_name="staff_member")
class Student(models.Model):
"""
A student can participate in some courses
"""
user = models.OneToOneField(ExtendedUser, related_name="student")
class Teacher(models.Model):
user = models.OneToOneField(ExtendedUser, related_name="teacher")
subjects = models.ManyToManyField(..)
class Parent(models.Model):
user = models.OneToOneField(ExtendedUser, related_name="parent")
children = models.ManyToManyField(Student, related_name=parents")
これは Django (および他の多くの MVC ベースのフレームワーク) で機能します。しかし、管理画面で上記を表示する適切な方法が見つかりません。
理想的には、ユーザーを追加してから、ユーザー変更ビュー内にさまざまな役割を追加したいと考えています。最初は、インラインを使用できると思いました:
class StudentInlineAdmin(admin.StackedInline):
model = Student
extra = 0
template = 'accounts/admin/role.html'
次に、インライン テンプレートに若干の変更を加えて、編集ユーザー ボタンに「学生ロールの追加」というキャプションを表示します。ボタンをクリックすると、フォームが表示され、ユーザー ロールが追加されます。理想的ではありませんが、機能します。
残念ながら、Staffmembers にはインライン フォームに追加するフィールドがありません。この方法では、インライン フォームの「has_changed」プロパティをトリガーすることはできません。これにより、新しい役割がデータベースに保存されません。
この最後の問題を解決するために、私は少しハックして空のユーザーロールに「ダミー」フォームフィールドを追加し、JS を使用してこのフィールドを非表示にしました。これにより、has_changed がトリガーされました。
それでも、後でいくつかのテスト中にインラインモデルが保存されない場合、これはうまくいきません。
だから私はそれを間違った方法でやっているだけだと思います。私は多くのグーグルを行い、多くの人が同じ種類の問題に悩まされていることを発見しました. 私の状況に最も適していたのはhttp://www.mail-archive.com/django-users@googlegroups.com/msg52867.htmlでした。しかし、それでもこのソリューションでは、管理者を簡単に実装する方法はありません。
組み込みのグループを使用することも考えましたが、その場合、さまざまなフィールドを追加する方法がわかりません。
私が考えたもう1つのことは、ユーザーを追加して彼に役割を割り当てる代わりに、「学生を追加」しようとすることでした。ユーザーを継承するだけの場合、これは管理者で非常にうまく機能します。
class StudentUser(auth.models.User):
pass
しかし、ここで 2 つの問題があります。最初はスタッフや教師になることはできません。2 つ目は、Django の残りの部分では、リクエスト オブジェクトが User オブジェクトを返し、そのために Student、Parent、Staffmember オブジェクトをリクエストすることが実際には機能していません。これらのいずれかを取得する唯一の方法は、User オブジェクトに基づいて新しい Student オブジェクトをインスタンス化することです。
Django と Django admin で機能するようにユーザーにロールを追加するには、どのタイプのモデル設計を使用する必要がありますか?
よろしく、 Wout