34

How can I do this cleanly in a Django template? Basically if A, or (B and C) , I want to show some HTML.

I basically have this:

{% if user.is_admin or something.enable_thing and user.can_do_the_thing %}

Now, thats a bit ambigious. I tried doing

{% if user.is_admin or (something.enable_thing and user.can_do_thething) %}

But you arent allowed Parentheses. The docs say to use nested ifs (or elifs in this case, i guess, as its an OR) , but I dont want to repeat the same HTML inside 2 if blocks, which sounds horrible.

2
  • leave it without paranthesis. I think it works ;) Commented Dec 15, 2014 at 15:05
  • 2
    You don't want to use nested if's and also parenthesis are invalid in if block, hence clearly framework does not support what you are asking for get over with it and move your complex logic to template tags or views. Commented Dec 15, 2014 at 15:13

4 Answers 4

21

As Mihai Zamfir commented it should work as expected. As Django documentation mentions:

Use of both and and or clauses within the same tag is allowed, with and having higher precedence than or e.g.:

{% if athlete_list and coach_list or cheerleader_list %}

will be interpreted like:

if (athlete_list and coach_list) or cheerleader_list

https://docs.djangoproject.com/en/2.2/ref/templates/builtins/#boolean-operators

Sign up to request clarification or add additional context in comments.

2 Comments

Could you provide a link to the official documentation as well? Helpful answer
And inverted: {% if athlete_list and coach_list or athlete_list and cheerleader_list %} would equal if athlete_list and (coach_list or cheerleader_list)
11

you could do the check in your view and pass a flag to the context.

show_html = user.is_admin or (something.enable_thing and user.can_do_the_thing) context['show_html'] = show_html 

Then in your template you could check the flag

{% if show_html %}

2 Comments

I wouldn't put this logic into a view but rather use a custom tag
What if one of those variables need to be a loop iteration variable? django disappointed me about this.
1

If you wish to do (A or B) and C you can do it like this:

{% if A or B %} {% if C %} ... {% endif %} {% endif %} 

If you wish to do A or (B and C), just do

{% if A or B and C %} ... {% endif %} 

Comments

0

If you have the case like you said: A or (B and C), then Sven's answer would work appropriately because the and would automatically have higher precedence according to the documentation.

However, if you wish to do something like (A or B) and C, then you could instead create and use custom template filters.

NOTE: Filters can only take at most two arguments, so they will only be useful if say, for example, you are comparing multiple attributes from 1 or 2 objects.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.