16

アプリの 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を管理してきました。この投稿によると、ユーザーが指し示している指示に従って、少し変更する必要があります。これは失敗でした。私の DB にはそれほど多くの情報が含まれていないため、South のコメントを外し、通常の syncdb を実行して South を除外しました。残念ながら、これはまだ機能しておらず、途方に暮れています。どんな助けでも大歓迎です。

編集

これはDjango 1.4でした

4

7 に答える 7

8

私は何も悪いことをしていないことがわかりました。私は下の許可を探していました

myapp | New Request | Can add new request

パーミッションは親モデルに分類されます。

myapp | engagement | Can add new request

于 2013-02-23T13:27:59.820 に答える
6

回避策があります。ここで確認できます: https://gist.github.com/magopian/7543724

django のバージョンによって異なる場合がありますが、原則は同じです。

Django 1.10.1 でテスト済み

# -*- 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/commands
  • ファイルを作成する/myproject/myapp/management/__init__.py
  • ファイルを作成する/myproject/myapp/management/commands/__init__.py
  • 上記のコードをに保存します/myproject/myapp/management/commands/fix_permissions.py
  • 走る/manage.py fix_permissions
于 2016-12-15T19:45:25.057 に答える
3

これは Django の既知のバグです: https://code.djangoproject.com/ticket/11154 (一部のパッチについてはコメントを確認してください)

于 2013-12-24T22:05:01.163 に答える
1

Django 1.11 の場合、この問題は、auth_permissionテーブルのcontent_type_idが間違っているために発生します。デフォルトでは、プロキシ モデルのコンテンツ タイプではなく、基本モデルのコンテンツ タイプが追加されます。

于 2018-04-11T11:44:03.887 に答える
0

この質問は少し前に閉じられたことに気付きましたが、他の人に役立つかもしれない場合に備えて、私にとって何がうまくいったかを共有しています.

私が作成したプロキシ モデルのアクセス許可は、( @chirinoskyのように) 親アプリの下にリストされていましたが、非スーパー ユーザーにすべてのアクセス許可を付与したにもかかわらず、プロキシ モデルへのアクセスは依然として拒否されていました。管理者。

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

これを、プロキシ モデルを保持する myapp/models.py に配置しました。理論的には、ハンドラーがシグナルに登録された後にロードして切断できるようにする必要があるため、これは任意のINSTALLED_APPS後に存在する可能性があります。django.contrib.contenttypesupdate_contenttypespost_syncdb

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)
于 2014-10-15T21:40:02.173 に答える