在 Django PermissionDenied 中发送自定义消息
Posted
技术标签:
【中文标题】在 Django PermissionDenied 中发送自定义消息【英文标题】:Send Custom message in Django PermissionDenied 【发布时间】:2014-10-12 03:49:47 【问题描述】:每当不允许用户访问任何页面时,我都会使用 django 的 PermissionDenied
来呈现 403.html
。
有很多不同类型的页面,例如Product page
、User Page
、User Contact information
、Owner 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
?
建议。
【问题讨论】:
你读过这个吗? docs.djangoproject.com/en/1.6/topics/http/views/… 是的,我有。我能够呈现 403.html,但那是静态的,对于所有 premissiondenied 响应都是一样的。我想发送一些关于请求类型的参数(上下文)并显示不同的消息。 你能解决这个问题@Clayton 吗? 是的。我能够@rka 【参考方案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
...
【讨论】:
以上是关于在 Django PermissionDenied 中发送自定义消息的主要内容,如果未能解决你的问题,请参考以下文章
当 conda install django, PermissionError(13, 'Permission denied')
/blog/create [Errno 13] Permission denied: '/static' during image upload in Django
Django-import-export-celery 导入错误 [Errno 13] 权限被拒绝
Nginx, django, gunicorn, ubuntu 14.04 (13: Permission denied) 同时连接到上游