2012-01-23 16 views
3

Django管理者の2つのユーザグループを区別するためのコードをいくつか作成しました。その結果、すべてのフィールドが読み込み専用になったり、ModelAdminクラスに直接設定されているフィールドだけが表示されます。django admin readonly_fieldsの理解

class PersonAdmin(admin.ModelAdmin): 
    readonly_fields = ('created_at','created_by',) 

def get_form(self, request, obj=None, **kwargs): 
    if obj:  # we are in edit mode 
     if request.user.is_superuser: 
      self.readonly_fields =() 
     else: 
      for group in request.user.groups.all(): 
       if str(group) == 'readonlyuser': 
        allfields = tuple(obj._meta.get_all_field_names()) 
        self.readonly_fields = allfields 

    return super(PersonAdmin, self).get_form(request, obj, **kwargs) 

Iはグループ間で分割し、それに応じてフィールドを設定:ここでまず

コードです。 2つのグループのユーザーが同時にログインしていない場合は、すべて正常に動作します。 「読み取り専用」ユーザーがログインした後、管理者はすべてのフィールドを読み取り専用にします。

私の点検はまた、溶液を提供する: を私はため内adminユーザーのためであれば、追加の文を入れた場合はすべてが期待どおりに動作しますブロックします。

if str(group) == 'adminuser': 
    self.readonly_fields = PersonAdmin.readonly_fields 

なぜ、何が起こっているのですか?

私は特別なキャッシュ設定をしていません。これはdevサーバーとWSGIを持つApacheで発生します。

私の理解から、request.user.groups.all()は、現在ログインしているのすべてのグループを返します。ユーザーが所属しています。 Djangoがどこから(readonly)allfieldを取得するのですか?別のIPとセッションの別のユーザがブロックした場合、これはどこですか?

答えて

12

ModelAdminは、受信したすべての要求に対して1回だけインスタンス化されます。だから、あなたはそれのような読み取り専用フィールドを定義するとき、あなたはボード全体に永久にそれを設定しています。

class MyModelAdmin(admin.ModelAdmin): 
    ... 

    def get_readonly_fields(self, request, obj=None): 
     if request.user.is_superuser: 
      return super(MyModelAdmin, self).get_readonly_fields(request, obj) 
     else: 
      return ('created_at', 'created_by') 

があなたのModelAdminからreadonly_fields属性を削除するか、そのべきフィールドに設定します。限り、あなたはDjangoの1.2+を実行しているとして、あなたはまさにこの目的のために代わりに使用することができますget_readonly_fields方法があります

全員のためだけに読んでください。次に、elseブロックに、スーパー以外のユーザーに対してのみ読み取り専用にすべきすべてのフィールドを指定します。

+0

ありがとうございました。私はすでにget_readonly_fieldsを使用していましたが、私はこの目的のために使用しないでください。 – normic

+0

この例では、obj引数は使用しませんが、常にNoneに設定されます。必要があります: 返すスーパー(MyModelAdmin、自己).get_readonly_fields(request、obj) – seddonym

+0

@seddonym:良いキャッチ。今修正されました。誰かが気づくのに1年半しかかかりませんでした;) –

1

ウェブサーバが再起動されたときに初めて実行された後、Django Adminのフィールドが設定(キャッシュ)されているためです。あなたはreadonly_fieldsタプルを再宣言することでそれを回避することができます。このような(テストされていない)もの:

def get_form(self, request, obj=None, **kwargs): 
    self.readonly_fields = ('created_at','created_by',) 
    # ...