Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/django/25.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Django代理模型权限不显示_Django_Django Models_Python 2.7_Django Admin_Django South - Fatal编程技术网

Django代理模型权限不显示

Django代理模型权限不显示,django,django-models,python-2.7,django-admin,django-south,Django,Django Models,Python 2.7,Django Admin,Django South,我为我的应用扩展了Django管理站点,允许非工作人员/超级用户访问。这很好用 我为现有模型创建了一个代理模型,并将其注册到我的管理站点,但是,它不会为非工作人员用户显示。从我阅读的文档中,我的理解是代理模型拥有自己的权限。我选中了,但这些不显示在可用权限列表中 以下是我的代码,以防有所帮助: 普通型号 class Engagement(models.Model): eng_type = models.CharField(max_length=5) environment = m

我为我的应用扩展了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 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)
自定义管理员注册

class NewRequestsAdmin(ModelAdmin):
pass

def queryset(self, request):
    return self.model.objects.filter(is_scoped=0)
myapps_admin_site.register(NewRequests, NewRequestsAdmin)
我一直在南方管理我的DB。根据我们的说法,你必须通过以下方式稍微修改它。这是一次失败。我的数据库中没有太多的信息,所以我取消了South的注释,并运行了一个常规的syncdb来排除South。不幸的是,这仍然不起作用,我不知所措。感谢您的帮助

编辑


这是在Django 1.4上的,结果证明我没有做错任何事。我正在寻找下的权限

myapp |新请求|可以添加新请求

权限属于父模型


myapp |订婚|可以添加新的请求

这是Django中的一个已知错误:(查看一些补丁的评论)

我意识到这个问题不久前已经解决了,但我正在分享对我有用的东西,以防它可能会帮助其他人

事实证明,即使我创建的代理模型的权限列在父应用(如前所述)下,即使我授予我的非超级用户所有权限,它仍然被拒绝通过管理员访问我的代理模型

我要做的是绕过一个已知的Django bug(),并连接到
post\u syncdb
信号,以便为代理模型正确创建权限。下面的代码是根据该线程上的一些注释修改的

我把它放在保存代理模型的myapp/models.py中。理论上,这可以在
django.contrib.contenttypes
之后的任何
INSTALLED\u应用程序中存在,因为它需要在
update\u contenttypes
处理程序注册
post\u 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)

有一个变通方法,您可以在此处看到:

它可以根据您的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/\uuuuu init\uuuuuu.py
  • 创建文件
    /myproject/myapp/management/commands/\uuuu init\uuuuu.py
  • 将上述代码保存到
    /myproject/myapp/management/commands/fix\u permissions.py
  • 运行
    /manage.py修复\u权限
适用于Django 1.11 与此问题相关的原因是auth\u permission表中的内容类型\u id错误。
默认情况下,它会添加基本模型的内容类型,而不是代理模型内容类型。

这在Django 2.2中已修复,引用:

代理模型的权限现在使用代理模型的内容类型而不是具体模型的内容类型创建。运行迁移时,迁移将更新现有权限

以及:

代理模型的工作方式与具体模型完全相同。权限是使用代理模型自己的内容类型创建的。代理模型不会继承其子类的具体模型的权限


我也有这个问题。你用的是什么版本的django?我在1.4中有相同的设置,但它没有解决,所以我想知道它是什么时候解决的?这也是在使用1.4。我不知道为什么它不能为你解决。我用这个版本更新了原来的帖子。我不知道你是怎么看的。根据Danny提到的bug报告,Django不会为代理模型创建权限。欢迎提供指向潜在解决方案的链接,但请提供链接,以便您的其他用户了解它是什么,以及它为什么存在。始终引用重要链接中最相关的部分,以防无法访问目标站点或永久脱机。考虑到仅仅是一个外部站点的链接是一个可能的原因。我会改进我的答案。谢谢@谢谢你的帮助。现在更好,也更有用。请注意,对于Django 1.11,您应该删除带有“name=…”的行