2013-02-23 22 views
7

私のアプリのDjango管理サイトを拡張し、スタッフ/スーパーユーザ以外のアクセスを許可しました。これはうまくいきます。Djangoプロキシモデルパーミッションが表示されない

既存のモデルのプロキシモデルを作成して管理サイトに登録しましたが、スタッフ以外のユーザーには表示されません。私が読んだドキュメントから、私の理解では、プロキシモデルには独自の権限が与えられます。私はチェックし、利用可能な権限のリストには表示されません。

ここに私のコードは、それが助け場合です:

ノーマルモデル

class Engagement(models.Model): 
    eng_type = models.CharField(max_length=5) 
    environment = models.CharField(max_length=8)  
    is_scoped = models.BooleanField()  

    class Meta: 
     ordering = ['eng_type', 'environment'] 
     app_label = 'myapp' 

プロキシモデル

class NewRequests(Engagement): 
    class Meta: 
     proxy = True 
     app_label = 'myapp' 
     verbose_name = 'New Request' 
     verbose_name_plural = 'New Requests' 

モデル管理

class NewRequestsAdmin(ModelAdmin): 
pass 

def queryset(self, request): 
    return self.model.objects.filter(is_scoped=0) 

カスタム管理者の登録

myapps_admin_site.register(NewRequests, NewRequestsAdmin) 

私は南と私のDBを管理してきました。 this postによれば、あなたはthe instructions it points users toに従うことによって少しそれを改ざんしなければなりません。これは失敗でした。私のDBには情報がたくさんあるので、私はサウスコメントを外し、通常のsyncdbを実行してSouthを除外しました。残念ながら、これはまだ動作していないと私は迷っています。どんな助けもありがとうございます。

編集これは

答えて

7

ジャンゴ1.4にあった私が間違って何もしませんでしたが判明します。私は

権限は親モデルに該当

myapp | New Request | Can add new request

下の権限を探していました。

myapp | engagement | Can add new request

+0

この問題もありました。 –

+0

あなたはどのバージョンのdjangoを使用していますか?私は1.4で同じ設定をしていますが、解決されていないので、いつ解決されたのだろうかと思います。 – fastmultiplication

+0

これは1.4も使用していました。なぜそれがあなたのために解決されていないか分かりません。元の投稿をバージョンで更新しました。 – chirinosky

2

これはジャンゴの既知のバグです:私はこの質問は、しばらく前に閉鎖された実現が、私は場合には私のために働いていたものを共有していhttps://code.djangoproject.com/ticket/11154(一部のパッチについてのコメントを確認してください)

1

それは他人を助けるかもしれない。

私が作成したプロキシモデルのアクセス許可は親アプリ(@chirinosky)の下に記載されていますが、スーパー以外のユーザーにすべてのアクセス許可を与えても、それでも私のアクセス権は拒否されていますプロキシモデルを管理者に提供します。

既知のDjangoバグ(https://code.djangoproject.com/ticket/11154)を回避し、post_syncdbシグナルに接続して、プロキシモデルのアクセス許可を正しく作成する必要がありました。以下のコードは、そのスレッドのコメントごとにhttps://djangosnippets.org/snippets/2677/から変更されています。

私はこれを私のプロキシモデルを保持するmyapp/models.pyに配置しました。理論的にはdjango.contrib.contenttypesの後のINSTALLED_APPSのいずれかに生きることができるので、シグナルのハンドラが登録された後にロードする必要があるため、ロードする必要があります。

def create_proxy_permissions(app, created_models, verbosity, **kwargs): 
    """ 
    Creates permissions for proxy models which are not created automatically 
    by 'django.contrib.auth.management.create_permissions'. 
    See https://code.djangoproject.com/ticket/11154 
    Source: https://djangosnippets.org/snippets/2677/ 

    Since we can't rely on 'get_for_model' we must fallback to 
    'get_by_natural_key'. However, this method doesn't automatically create 
    missing 'ContentType' so we must ensure all the models' 'ContentType's are 
    created before running this method. We do so by un-registering the 
    'update_contenttypes' 'post_syncdb' signal and calling it in here just 
    before doing everything. 
    """ 
    update_contenttypes(app, created_models, verbosity, **kwargs) 
    app_models = models.get_models(app) 
    # The permissions we're looking for as (content_type, (codename, name)) 
    searched_perms = list() 
    # The codenames and ctypes that should exist. 
    ctypes = set() 
    for model in app_models: 
     opts = model._meta 
     if opts.proxy: 
      # Can't use 'get_for_model' here since it doesn't return 
      # the correct 'ContentType' for proxy models. 
      # See https://code.djangoproject.com/ticket/17648 
      app_label, model = opts.app_label, opts.object_name.lower() 
      ctype = ContentType.objects.get_by_natural_key(app_label, model) 
      ctypes.add(ctype) 
      for perm in _get_all_permissions(opts, ctype): 
       searched_perms.append((ctype, perm)) 

    # Find all the Permissions that have a content_type for a model we're 
    # looking for. We don't need to check for codenames since we already have 
    # a list of the ones we're going to create. 
    all_perms = set(Permission.objects.filter(
     content_type__in=ctypes, 
    ).values_list(
     "content_type", "codename" 
    )) 

    objs = [ 
     Permission(codename=codename, name=name, content_type=ctype) 
     for ctype, (codename, name) in searched_perms 
     if (ctype.pk, codename) not in all_perms 
    ] 
    Permission.objects.bulk_create(objs) 
    if verbosity >= 2: 
     for obj in objs: 
      sys.stdout.write("Adding permission '%s'" % obj) 


models.signals.post_syncdb.connect(create_proxy_permissions) 
# See 'create_proxy_permissions' docstring to understand why we un-register 
# this signal handler. 
models.signals.post_syncdb.disconnect(update_contenttypes) 
3

回避策はありますが、あなたはここでそれを見ることができます:https://gist.github.com/magopian/7543724

をそれはあなたのDjangoのバージョンに基づいて変更することができますが、pricipleは同じです。ジャンゴ1.10.1ディレクトリ/myproject/myapp/management/commands

  • を作成
    • を使用する方法

      # -*- coding: utf-8 -*- 
      
      """Add permissions for proxy model. 
      This is needed because of the bug https://code.djangoproject.com/ticket/11154 
      in Django (as of 1.6, it's not fixed). 
      When a permission is created for a proxy model, it actually creates if for it's 
      base model app_label (eg: for "article" instead of "about", for the About proxy 
      model). 
      What we need, however, is that the permission be created for the proxy model 
      itself, in order to have the proper entries displayed in the admin. 
      """ 
      
      from __future__ import unicode_literals, absolute_import, division 
      
      import sys 
      
      from django.contrib.auth.management import _get_all_permissions 
      from django.contrib.auth.models import Permission 
      from django.contrib.contenttypes.models import ContentType 
      from django.core.management.base import BaseCommand 
      from django.apps import apps 
      from django.utils.encoding import smart_text 
      
      class Command(BaseCommand): 
          help = "Fix permissions for proxy models." 
      
          def handle(self, *args, **options): 
           for model in apps.get_models(): 
            opts = model._meta 
            ctype, created = ContentType.objects.get_or_create(
             app_label=opts.app_label, 
             model=opts.object_name.lower(), 
             defaults={'name': smart_text(opts.verbose_name_raw)}) 
      
            for codename, name in _get_all_permissions(opts): 
             p, created = Permission.objects.get_or_create(
              codename=codename, 
              content_type=ctype, 
              defaults={'name': name}) 
             if created: 
              sys.stdout.write('Adding permission {}\n'.format(p)) 
      

      でテスト

      は、ファイルを作成/myproject/myapp/management/__init__.py

    • コードファイルを保存し/myproject/myapp/management/commands/__init__.py
    • を作成上記のに210
    • 実行/manage.py fix_permissions
  • +0

    潜在的なソリューションへのリンクはいつでも歓迎しますが、[リンクの前後にコンテキストを追加]してください(http://meta.stackexchange.com/questions/8231/are-answers-that-just-contain-links-elsewhere-really -good-answers/8259#8259)、あなたの仲間のユーザーは、それが何であるか、なぜそこにいるのかを知るでしょう。ターゲットサイトに到達できない場合や、永続的にオフラインになる場合は、常に重要なリンクの最も関連性の高い部分を引用してください。外部サイトへのリンク以上になることは、[なぜ、どのように答えが削除されるのか?](http://stackoverflow.com/help/deleted-answers)という理由が考えられます。 – FelixSFD

    +0

    私は私の答えを改善します。ありがとう! – vinagreti

    +0

    @FelixSFDご協力ありがとうございます。今ははるかに良く役立ちます。 – vinagreti

    関連する問題