2017-07-17 14 views
1

に基づいて制限ユーザー「を削除/変更することができます」権限はだから私は、Djangoの認証ユーザモデルを拡張するために、1対1のフィールドを追加しました:ジャンゴ:1対1のフィールド

class Employee(models.Model): 
    user = models.OneToOneField(User, on_delete=models.CASCADE) 
    division = models.ForeignKey(Division, on_delete=models.CASCADE) 

私が欲しいもの達成するためには、すべての従業員が他の従業員オブジェクトを変更する権限を持ちますが、その従業員が属する部門に属するものに限定されます。

私は、ユーザーと従業員オブジェクトを追加/変更/削除する権限を持つ「従業員」アクセス許可グループを作成しました。

は今、各従業員は、ユーザーオブジェクトの両方の従業員のすべてすべてのための「変更できるの許可を持っています。

私はOneToOneFieldでdjangoの管理変更リストをフィルタリングして、各従業員だけが変更リスト内の自分の部門から従業員を見ることができました。

問題は、別の部門のユーザーを変更するために手動でURLを入力すると、ユーザーがこのユーザーを変更または削除できるということです。同様に、スーパーユーザー(ユーザー1)も変更/削除することができます。次へ移動:

http://localhost:8000/admin/auth/user/1/change/ 

トリックを行います。

この問題を解決する私のアイデアは、authユーザー変更メソッドをオーバーライドして 'division-or-superuser'チェックを追加することでしたが、これはハッキーです。部門別に変更URLへのアクセスを制限したいのですが、これを達成する方法はまだ見つかりませんでした。

ありがとうございました!

答えて

1

クラスベースのビューでUserPassesTestMixinを使用すると、現在のユーザーが強制的に変更しようとしている従業員の部門に対してテストすることができます。

change方法は、以下の例えばPOST方法であると仮定すると:

from django.contrib.auth.mixins import UserPassesTestMixin 

class MyView(UserPassesTestMixin, View): 

    def test_func(self): 
     ch_user_division = Employee.objects.filter(
      pk=self.request.POST.get('user_id') 
     ).values('division') 
     return self.request.user.division == ch_user_division 

今、ユーザが変更するようにユーザが同じ区分にある場合MyViewチェックをベースクラス。https://docs.djangoproject.com/en/1.11/topics/auth/default/#limiting-access-to-logged-in-users-that-pass-a-testコメントレガシー上の理由から、次を残し


:ユーザーのアクセスを制限する方法についての更なる情報については

あなたは、モデル定義にどのForeignKey.limit_choices_to引数を使用することができます。

Sets a limit to the available choices for this field when this field is rendered using a ModelForm or the admin .

以下を試してください:

class Employee(models.Model): 
    user = models.OneToOneField(
     User, 
     on_delete=models.CASCADE, 
     limit_choices_to={'division': division} 
    ) 
    division = models.ForeignKey(Division, on_delete=models.CASCADE) 

+0

ありがとうございます:良い解決策と思われます。しかし、私はそれを試して、それはNameErrorを投げた:名前 '自己'は定義されていません.. – DeBaze

+0

私はlimit_choices_toが使用されることができると思うので、それは少し詳細を洗練される必要があります: '従業員':**すべて従業員は「自己決定」**に接続していますか? – DeBaze

+0

@DeBazeは私が今テストする設定がないので、 'self.'を省略して(上記の私の編集のように)、動作するかどうかを知らせてみてください。 –

1

私は次のように既存のUSERADMINクラスchange_viewメソッドをオーバーライドし、(彼は正しい方向に私を指摘したので、私は受け入れた)上記のジョンの答えの組み合わせを使用して私の問題を修正:

from django.contrib.auth.admin import UserAdmin as BaseUserAdmin 

class SelectiveUser(BaseUserAdmin): 
    def change_view(self, request, object_id, form_url=''): 

    if request.user.is_superuser: 
     return super(SelectiveUser, self).change_view(
      request, object_id, form_url,) 

    # logic to check using John's method above or another way 

    # if check passes, return super(etc....) as above for superuser 
    # if not, return 403 



admin.site.unregister(User) 
admin.site.register(User, SelectiveUser) 

私はdelete_viewについても同じことをしました