gpt4 book ai didi

django - 如何编写用于访问控制的 Django 模板标记?

转载 作者:行者123 更新时间:2023-12-01 11:07:32 27 4
gpt4 key购买 nike

我试图创建一个简单的 Django 模板标记来显示或隐藏我网站上提交的评论旁边的“删除”链接,但没有成功。

简而言之,我想将评论对象传递给模板标签,判断当前登录的用户是否有权删除评论,然后显示或不显示链接。

我的模板中的用法是这样的:

{% load access_tags %}
{% if_authorized comment %}
<a href="{% url delete_comment comment.id %}">Delete</a>
{% endif_authorized %}

请放心,如果用户有权删除评论,我也会检查相应的 View 。

这种标签有具体的名称吗?如果可以的话,它肯定会帮助我进行谷歌搜索。感谢您的帮助!

更新 1:

根据我网站的运作方式,可能有两个人有权删除评论:1) 评论创建者和 2) 发表评论的帖子的所有者。因此,我需要根据评论确定是否存在其中一个条件。

我不认为我可以使用像 Django 的内置权限系统这样的东西,因为它要求权限“针对每种类型的对象进行全局设置,而不是针对每个特定的对象实例”。

在我的例子中,用户“Bob”可能有删除评论的权限(如果他写的或在他创建的帖子上),但他也可能不被允许删除它(如果他正在查看评论别人的帖子)。

更新 2:

It appears that you can't pass objects to a template tag, only strings: "Although you can pass any number of arguments to a template tag using token.split_contents(), the arguments are all unpacked as string literals." I guess I'll pass the id of the comment object in question and pull it in the tag.

我错了,只需要像这样访问传入的对象:

self.comment.resolve(context).user 

对比

self.comment.user

最佳答案

好吧,我就是这样做的......

标签在模板中是这样使用的:

   {% 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 %} 标签来做这个比较会很容易,但由于我还有其他每个对象的授权要做,我将继续构建这些自定义“访问标签”。另外,模板代码看起来更整洁:)

关于django - 如何编写用于访问控制的 Django 模板标记?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3773995/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com