【问题标题】:Send Custom message in Django PermissionDenied在 Django PermissionDenied 中发送自定义消息
【发布时间】:2014-10-12 03:49:47
【问题描述】:

每当不允许用户访问任何页面时,我都会使用 django 的 PermissionDenied 来呈现 403.html

有很多不同类型的页面,例如Product pageUser PageUser Contact informationOwner Information

我想添加带有PermissionDenied 的自定义消息,这将告诉用户他无法查看此页面的确切原因。我想将以下动态消息添加到403.html

You have are trying to `View a Product (id:3094384)` while having a `Trail` account. You are not authorized to view this product. 

 You have are trying to `View a Customer (id:48)` which is Private. You are not authorized to view this User. 

等等。

这是我的代码

elif role.id == Project.ROLE_SALES and not project.sales_person_id == user_id:
            raise PermissionDenied

html

<body class="error-page">

<!--  content -->
<section>
    <div class="error403">
        <h1>403</h1>
    </div>
    <p class="description">Oops! Request forbidden...</p>

    <p>Sorry, it appears the page you were looking for is forbidden and not accessible. If the problem persists, please
        contact web Administrator.</p>


# HERE I WANT TO SHOW DYNAMIC MESSAGE. 



    <a href="{{ request.META.HTTP_REFERER }}" class="btn btn-danger403 btn-primary btn-large" >
        Go Back </a>
{{ except }}
</section>



<script src="{% static 'js/jquery.min.js' %}"></script>
<script src="{% static 'js/bootstrap.js' %}"></script>
</body>

可能性

raise PermissionDenied("Custom message")

或者

将上下文传递给PermissionDenied?

建议。

【问题讨论】:

  • 是的,我有。我能够呈现 403.html,但那是静态的,对于所有 premissiondenied 响应都是一样的。我想发送一些关于请求类型的参数(上下文)并显示不同的消息。
  • 你能解决这个问题@Clayton 吗?
  • 是的。我能够@rka

标签: python django views decorator permission-denied


【解决方案1】:

这个答案对你来说可能来得太晚了。但在这里。 您可以在 Django 代码中使用它:

raise PermissionDenied("Custom message")

然后在 403.html 模板中使用下面的 sn-p 显示自定义消息:

{% if exception %}
  <p>{{ exception }}</p>
{% else %}
  <p>Static generic message</p>
{% endif %}

传递给“PermissionDenied”的消息字符串在模板上下文中可用,如 Django 文档中所述 - https://docs.djangoproject.com/en/1.10/ref/views/#http-forbidden-view

【讨论】:

  • 我也面临着类似的困境。你能检查我的问题here吗?
【解决方案2】:

我遇到了同样的问题,并使用 Django 消息框架将自定义消息传递给模板来解决它。

https://docs.djangoproject.com/en/1.8/ref/contrib/messages/

我的具体例子:

from django.contrib import messages
...
messages.error(request, 'The submission deadline has passed.')
raise PermissionDenied

然后可以按照文档中的说明在模板中输出消息。

【讨论】:

    【解决方案3】:

    如果您使用基于类的视图 (CBV) 或任何扩展 AccessMixin 的东西,请设置 permission_denied_message 属性或覆盖 get_permission_denied_message 方法。

    例子:

    from django.conf import settings
    
    class MyView(ListView):
        permission_denied_message = 'Hooo!'
    
        def get_permission_denied_message(self):
            perms = self.get_permission_required()
            if settings.DEBUG:
                for perm in perms:
                    if not self.request.user.has_perm(perm):
                        return 'Permission denied: ' + str(perm)
            return ''
    

    然后,在您的模板中:

    {% if exception and debug %}
        <h3 class="font-bold">{{ exception }}</h3>
    {% endif %}
    

    【讨论】:

    • 我只在开发中渲染权限被拒绝,因此,DEBUG 被选中。
    【解决方案4】:

    你可以这样试试:

    class SomeException(Exception):
        message = 'An error occurred.'
    
        def __init__(self, message):
            self.message = message
    
        def __str__(self):
            return repr(self.message)
    
    #usage
     raise SomeException("Hello, you have an exception here")
    

    向模板发送消息的另一种方式是:

    if not request.user.is_staff: #or your condition
       context['flash_message']= "permission error occurred"
       retrun render_to_response('template.html', context)
    
    # template
    <!-- I am using bootstrap here -->
    <div class="alert alert-{{ flash_message_type }} flash_message hide">
        {{ flash_message | safe }}
    </div>
    
    <script>
    ...
    if($.trim($(".flash_message").html()) != ''){
            $(".flash_message").slideDown();
            setTimeout(function(){
                $(".flash_message").slideUp();
            }, 5000);
        };
    </script>
    

    【讨论】:

    • 这不是我想要的。我想将用户重定向到只显示错误的新页面。 PremissionDenied 总是显示一页 403.html 但我想显示自定义消息。
    【解决方案5】:

    同样的问题。

    django 1.9 we have this built in。在最早的 django 版本中,我们可以使用sys.exc_info(),所以下一步就是重用整个默认的permission_denied 处理程序来添加我们的异常。

    # urls.py
    ...
    handler403 = 'project.views.errors.permission_denied'
    ...
    
    # views/errors.py
    import sys
    
    from django import http
    from django.template import Context, TemplateDoesNotExist, loader
    from django.views.decorators.csrf import requires_csrf_token
    
    
    @requires_csrf_token
    def permission_denied(request, template_name='403.html'):
        _, value, _ = sys.exc_info()
    
        try:
            template = loader.get_template(template_name)
        except TemplateDoesNotExist:
            return http.HttpResponseForbidden('<h1>403 Forbidden</h1>', content_type='text/html')
        return http.HttpResponseForbidden(
            template.render(request=request, context={'exception': force_text(value)})
        )
    
    # templates/403.html
    ...
    {{ exception }}
    ...
    

    【讨论】:

      猜你喜欢
      • 2021-11-18
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-01-02
      • 2019-06-28
      • 1970-01-01
      • 1970-01-01
      • 2011-06-28
      相关资源
      最近更新 更多