How to write better template tags in django

陌路散爱 提交于 2019-12-21 06:07:28

问题


I've seen how I can write template tags that set a context variable based on a template like this

{% my_template_tag 'blah' as my_context_variable %}

But I'd like to be able to do this:

given that both group and user are set in the context in the view

{% is_in_group group user as is_member %}

{% if is_member %}
   #.... do stuff ....
{% endif %}

or ideally something like this:

{% if is_in_group group user %}
   # ....
{% end if %}

Obviously the other way round is to just set is_member in the view - but this is just an example and would be good to know how to do something like this anyway!


回答1:


Evgeny has a good idea with the smart_if template tag. However, if that doesn't work, you will probably find that a custom filter is easier to write for this sort of comparison. Something like:

@register.filter
def is_in(obj, val):
    return val is in obj

and you would use it like this:

{% if user|is_in:group.users %}



回答2:


What's wrong with {{ perms.model_name.permission_name }}? (Comes with django.core.context_processors.auth.)

Django groups are just collections of permissions, and allowing or disallowing access to a particular item should be by individual permission.

Or, if you really want to write your own tag or filter, there's lots of documentation. And if that doesn't work, there are other template languages that you can use that might do what you want better.

However, I expect that writing a tag will be unnecessary. Django is pretty good at having already figured out what you really want to do. Sometimes it takes a little digging to find out though.




回答3:


try this using smart if tag:

{% if group in user.groups %}
    ...
{% endif %}



回答4:


Daniel's filter should do the trick. As a template tag it could be something like this:

class IsInGroupNode(Node):
    def __init__(self, group, user, varname):
        self.member =  template.Variable(user)
        self.group = template.Variable(group)
        self.varname = varname


    def render(self, context):
        self.group = self.group.resolve(context)
        self.user = self.user.resolve(context)
        context[self.varname] = self.user in self.group.user_set.all()
        return  ''


def is_in_group(parser, token):
    bits = token.contents.split()
    #some checks
    return IsInGroupNode(bits[1], bits[2],bits[4])

is_in_group = register.tag(is_in_group)

In the template you would use your tag signature

{% is_in_group group user as is_member %}


来源:https://stackoverflow.com/questions/1827976/how-to-write-better-template-tags-in-django

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!