views:

334

answers:

4

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!

+3  A: 

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.

Seth
sorry - the use of `groups` was a bit confusing - in this case I have groups in my app (not auth groups) and in particular wanted to see if the current user was a member of the current 'group' - if not, then show a "join group" button, if so, show a "leave group" button.
Guy Bowden
+2  A: 

try this using smart if tag:

{% if group in user.groups %}
    ...
{% endif %}
Evgeny
+9  A: 

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 %}
Daniel Roseman
genius. use a filter not a tag - didn't think of that!
Guy Bowden
A: 

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

untested

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 %}
vikingosegundo