at_yasu's blog

ロード的なことを

[django] Djangoメモ書き permisson

Djangoの管理画面などを操作する際、ユーザに付与されているパーミッションを元に、操作するしないなどといったユーザの細かい操作ができる。

パーミッションはグループにも割り当てられる。


例えば、ものすごく簡易的なショッピングサイトを作っているとしよう。ユーザには商品のみを扱う人と管理者の二通りに分けられる。商品のみを扱う人は、shopグループに属しておりDjangoの管理者では無い人になる。

商品モデルとして、goodsモデルというのがあるとする。詳しい内容は省きます。面倒なので。そして、商品しか扱わないshopグループはgoodsパッケージのみのパーミッションを割り当てる。

すると、test2ユーザはgoodsパッケージしか操作することができない。*1

ただし管理者はすべてのモデルを扱うことができる。


なおユーザ単位にもパーミッションを割り当てることができる。test2にauthパッケージの閲覧権限を付与した場合、test2にできることは、authパッケージの閲覧およびgoodsパッケージの操作となる。

Django.contrib.auth.Userモデル

Userのパーミッションメソッド周り

  • 一覧を取得。List型で返す
    • get_group_permissions
      • 付与されているグループのパーミッションリストを返す
    • get_all_permissions
      • グループ+自信に割り当てられているパーミッションリストを返す
  • パーミッションがあるか確認。Bool型で返す
    • has_perm(Perm)
      • Permは文字列で、"package.codename"という形式で表す。例えば"goods.add_goods_image"だと、goodsパッケージのadd_goods_imageコードとなる。
    • has_perms([Perm])
      • 引数はPermのList型で渡す。List内のいずれかに当たればTrueを返す
    • has_module_perms(package_name)
      • packageのパーミッションが付与されている場合のみ、Trueを返す


以下例

>>> u = User.objects.get(username="test2")
>>> u
<User: test2>
>>> u.groups
<django.db.models.fields.related.ManyRelatedManager object at 0x1004c10>
>>> u.groups.all()
[<Group: Shop>]
>>> u.get_group_permissions()
set([u'goods.delete_matchgoods', u'goods.add_goods_image', u'goods.delete_send_package', u'goods.change_paytype', u'goods.delete_goods', u'goods.change_matchvalue', u'goods.add_goods', u'goods.add_matchkey', u'goods.change_send_package', u'goods.delete_paytype', u'goods.delete_matchvalue', u'goods.add_matchgoods', u'goods.change_genre', u'goods.change_matchkey', u'goods.change_matchgoods', u'goods.add_paytype', u'goods.delete_goods_image', u'goods.delete_genre', u'goods.change_goods', u'goods.delete_matchkey', u'goods.add_genre', u'goods.change_goods_image', u'goods.add_send_package', u'goods.add_matchvalue'])
>>> u.get_all_permissions()
set([u'goods.delete_matchgoods', u'goods.add_goods_image', u'goods.delete_send_package', u'goods.change_paytype', u'goods.delete_goods', u'goods.change_matchvalue', u'goods.change_matchkey', u'goods.add_goods', u'goods.add_matchkey', u'goods.change_send_package', u'goods.delete_paytype', u'goods.delete_matchvalue', u'goods.add_matchgoods', u'goods.change_genre', u'goods.change_matchgoods', u'goods.add_paytype', u'goods.delete_goods_image', u'goods.delete_genre', u'goods.change_goods', u'goods.add_send_package', u'goods.add_genre', u'goods.change_goods_image', u'goods.delete_matchkey', u'goods.add_matchvalue'])
>>> u.has_perm(u'goods.change_matchvalue')
True
>>> u.has_perm(u'goods.change_test')
False
>>> u.has_module_perms(u'goods')
True
>>> u.has_module_perms(u'account')
False
>>> 

Adminサイトの挙動

割り当てられてないパーミッションのパッケージは、表示しない。

例えば上記のアプリケーションにはaccountなどがあるが、test2ユーザはgoods周りのパーミッションしか割り当ててないため、Djangoの標準管理画面ではgoodsしか表示されない。

私がドキュメントの読み足りないせいか、実際に実験するまで、どこにこの事が書いているかわからなかった。

Permissionの新規作成

Permissionの一覧に必要な物が無く、自分で作成したい場合があると思う。その場合は、Modelのメタクラスで定義する。

Metaクラス内に、Permissionsというタプル型のを記入する。中のタプルは(permission code, human readble permission code) という文法になる。


なおsyncdbをすると、PermissionテーブルにPermissionを追加する。

class testModel (models.Model):
    class Meta:
        permissions = (("test_user", "test user"), ("first_test", "first test"))

まだわからない事

addとchangeとdeleteはモデルに何も宣言しなくても自動で付与すると書いているが、他にもいろいろある。これらは何…?

*1:Djangoにバグがない限り