【问题标题】:How to enable a user to view the django admin home page if nothing but a custom view permission in given to the user?如果仅授予用户自定义查看权限,如何使用户能够查看 django 管理主页?
【发布时间】:2017-04-22 19:46:43
【问题描述】:

通过在我的一个模型中添加以下代码,我能够为模型添加查看权限。

class Meta:
    default_permissions = ('add', 'change', 'delete', 'view')

我在 django-admin 中创建了一个用户并且只授予查看权限。我希望用户应该只能查看这个特定模型的值。

但是在与用户登录后,我收到一个错误,即用户无权编辑任何内容。(请参阅屏幕截图)。

有什么方法可以让用户仅通过授予 VIEW 权限来查看特定模型?任何帮助将不胜感激。

【问题讨论】:

    标签: django django-admin django-permissions


    【解决方案1】:

    这涉及相当麻烦。我将在下面转储一些想法。

    首先,让我们在管理员中展示一个具有view 权限的模型:

    from django.contrib import admin
    from django.contrib.auth import get_permission_codename
    
    from .models import MyModel
    
    
    @admin.register(MyModel)
    class MyModelAdmin(admin.ModelAdmin):
    
        def get_model_perms(self, request):
            model_perms = super(MyModelAdmin, self).get_model_perms(request)
    
            view_perm = self.has_view_permission(request)
    
            model_perms.update({
                'change': view_perm,
                'view': view_perm,
            })
    
        def has_view_permission(self, request):
            opts = self.opts
            codename = get_permission_codename('view', opts)
            return request.user.has_perm("%s.%s" % (opts.app_label, codename))
    

    注意:我正在连接changelist_view()。我发现它更容易。

    其次,让我们在MyModelAdmin 中添加两个视图viewlist_view()view_view()

    def get_urls(self):
        from django.conf.urls import url
    
        def wrap(view):
            def wrapper(*args, **kwargs):
                return self.admin_site.admin_view(view)(*args, **kwargs)
            wrapper.model_admin = self
            return update_wrapper(wrapper, view)
    
        info = self.model._meta.app_label, self.model._meta.model_name
    
        urlpatterns = super(MyModelAdmin, self).get_urls()
        urls = [
            url(r'^viewlist/$', wrap(self.viewlist_view), name='%s_%s_viewlist' % info),
            url(r'^(.+)/view/$', wrap(self.view_view), name='%s_%s_view' % info),
        ]
    
        return urls + urlpatterns
    
    @csrf_protect_m
    def viewlist_view(self, request, extra_context=None):
        opts = self.model._meta
        app_label = opts.app_label
        if not self.has_view_permission(request):
            raise PermissionDenied
    
        context = dict(
            self.admin_site.each_context(request),
            title='%s view list' % force_text(opts.verbose_name),
            queryset=self.get_queryset(request),
        )
        context.update(extra_context or {})
    
        return TemplateResponse(request, 'admin/view_list.html', context)
    
    @csrf_protect_m
    def view_view(self, request, object_id, extra_context=None):
        opts = self.model._meta
        app_label = opts.app_label
        if not self.has_view_permission(request):
            raise PermissionDenied
    
        context = dict(
            self.admin_site.each_context(request),
            object_id=object_id,
        )
    
        return TemplateResponse(request, 'admin/view_view.html', context)
    

    第三,钩入changelist_view()

    @csrf_protect_m
    def changelist_view(self, request, extra_context=None):
        if not self.has_change_permission(request, None):
            # or redirect
            return self.viewlist_view(request, extra_context)
        return super(MyModelAdmin, self).changelist_view(request, extra_context)
    

    第四,添加两个模板:

    admin/view_list.html

    {% extends "admin/base_site.html" %}
    
    {% block content %}
    <div id="content-main">
      <ul>
        {% for obj in queryset %}
          <li><a href="{{ obj.get_admin_view_url }}">{{ obj }}</a></li>
        {% endfor %}
      </ul>
    </div>
    {% endblock %}
    

    admin/view_view.html

    {% extends "admin/base_site.html" %}
    
    {% block content %}
    <div id="content-main">
    
    {{ object_id }}
    
    </div>
    {% endblock %}
    

    最后,我在MyModel 中添加了一个方法get_admin_view_url() 以进入管理视图:

    from __future__ import unicode_literals
    
    from django.db import models
    from django.core.urlresolvers import reverse
    
    
    class MyModel(models.Model):
        name = models.CharField(max_length=255)
    
        class Meta:
            default_permissions = ('add', 'change', 'delete', 'view')
    
        def __unicode__(self):
            return self.name
    
        def get_admin_view_url(self):
            info = (self._meta.app_label, self._meta.model_name)
            return reverse('admin:%s_%s_view' % info, args=(self.id,))
    

    我希望这是有道理的。

    【讨论】:

    • 感谢@twil 的回答。让我实现同样的,看看代码是否有效。
    猜你喜欢
    • 2016-08-04
    • 2015-12-05
    • 1970-01-01
    • 1970-01-01
    • 2011-03-07
    • 1970-01-01
    • 2012-02-25
    • 2011-02-20
    • 2021-09-25
    相关资源
    最近更新 更多