我正在尝试创建一个简单的Django模板标记,以显示或隐藏我网站上提交的评论旁边的“删除”链接。
简而言之,我想将评论对象传递给模板标签,确定当前登录的用户是否有权删除评论,然后显示或不显示链接。
我模板中的用法如下:
{% load access_tags %}
{% if_authorized comment %}
<a href="{% url delete_comment comment.id %}">Delete</a>
{% endif_authorized %}
请放心,如果用户有权删除评论,我也会检查相应的视图。
这种类型的标签是否具有特定名称?如果有的话,它肯定会帮助我进行谷歌搜索。谢谢你的帮助!
更新1:
我的网站的工作方式,有两个人可能有权删除评论:1)评论创建者和2)评论留下的帖子的所有者。因此,我需要根据评论确定是否存在其中一个条件。
我认为我不能使用像Django的内置权限系统这样的东西,因为它要求“根据每种类型的对象设置全局权限,而不是每个特定的对象实例”。
在我的情况下,用户“Bob”可能有权删除评论(如果他写的或是在他创建的帖子上),但他也可能不被允许删除(如果他正在查看评论别人的帖子。)
更新2:
看来你不能将对象传递给模板标签,只能传递字符串:“尽管你可以使用token.split_contents()将任意数量的参数传递给模板标签,但参数都被解压缩为字符串文字“。我想我会传递相关评论对象的id并将其拉入标签。
我错了,只需访问传入的对象,如:
self.comment.resolve(context).user
VS
self.comment.user
答案 0 :(得分:2)
答案 1 :(得分:2)
如何...创建writes a variable in the context的自定义标记,然后使用{% if %}
它是这样的:
{% check_access comment %}
{% if has_access %}
<a href="{% url delete_comment comment.id %}">Delete</a>
{% endif %}
当然“check_access”标签会在上下文中写入“has_access”。
祝你好运
答案 2 :(得分:2)
好的,我就这样做了......
标签在模板中使用如下:
{% load access_tags %}
{% if_authorized comment.user object.user user %}
<a href="{% url delete_comment comment.id %}">Delete</a>
{% endif_authorized %}
模板标记文件名为“access_tag.py”,位于我的应用程序的“templatetags”目录中。这是“access_tag.py”的内容:
from django.template import Node, NodeList, TemplateSyntaxError
from django.template import Library, Variable, VariableDoesNotExist
register = Library()
def do_if_authorized(parser, token):
"""
Outputs the contents of the block if the 'comment owner' or the
'page owner' is also the 'authenticated user'. As well, you can use
an {% else %} tag to show text if the match fails.
Takes three parameters:
1) the comment owner
2) the page owner
3) the current authenticated user
"""
bits = token.contents.split()
if len(bits) != 4:
raise TemplateSyntaxError("%s tag takes three arguments: \
1) the comment owner \
2) the page owner \
3) the current authenticated user" % bits[0])
nodelist_true = parser.parse(('else', 'endif_authorized'))
token = parser.next_token()
if token.contents == 'else':
nodelist_false = parser.parse(('endif_authorized',))
parser.delete_first_token()
else:
nodelist_false = NodeList()
return IfAuthorizedNode(bits[1], bits[2], bits[3], nodelist_true, nodelist_false)
class IfAuthorizedNode(Node):
def __init__(self, comment_owner, page_owner, authenticated_user, nodelist_true, nodelist_false):
self.nodelist_true = nodelist_true
self.nodelist_false = nodelist_false
self.comment_owner = Variable(comment_owner)
self.page_owner = Variable(page_owner)
self.authenticated_user = Variable(authenticated_user)
def render(self, context):
try:
comment_owner = self.comment_owner.resolve(context)
page_owner = self.page_owner.resolve(context)
authenticated_user = self.authenticated_user.resolve(context)
except VariableDoesNotExist:
return ''
if comment_owner == authenticated_user or page_owner == authenticated_user:
return self.nodelist_true.render(context)
else:
return self.nodelist_false.render(context)
register.tag('if_authorized', do_if_authorized)
完成。最后,使用内置的{%if%}标记来进行此比较非常容易,但由于我还有其他每个对象的授权,我将继续构建这些自定义“access_tags”。另外,模板代码看起来更整洁:)