netimen
netimen

Reputation: 4419

Django: is variables in templates a good idea?

I'm quite new to Django and HTML. I have the following in my template:

{% if user.is_authenticated  %}
    <a href='{% url 'vote' %}' id='story-vote-{{ story.id }}' class='vote'><img src='{{ STATIC_URL }}images/arrow.gif'></a>
{% else %}
    <a href='{% url 'login' %}' id='story-vote-{{ story.id }}' class='vote'><img src='{{ STATIC_URL }}images/arrow.gif'></a>
{% endif %}

So only the URL differs, but the id and image are the same. How to avoid this repetition? I would do something like this:

{% var link %} {# pseudo-code #}
{% if user.is_authenticated  %}
    link = 'vote'
{% else %}
    link = 'login'
{% endif %}
<a href='{% url link %}' id='story-vote-{{ story.id }}' class='vote'><img src='{{ STATIC_URL }}images/arrow.gif'></a>

Is it a good idea? I know that Django doesn't support local variables, but there are site-packages for this. Or is it better to handle the logic in the view and to pass link as a parameter to the template?

So what's the true Django way?

Upvotes: 1

Views: 141

Answers (3)

Wolfmetr
Wolfmetr

Reputation: 51

True Django way to handle the logic to the view or create User method for this. You can in views.py

def index(request):
    def can_vote():
        if request.user.is_authenticated:
            return 'vote'
        return 'login'

    user = request.user
    user.vote = can_vote
    ...

and then in template you can

<a href='{% url user.vote %}' id='story-vote-{{ story.id }}' class='vote'><img src='{{ STATIC_URL }}images/arrow.gif'></a>

Upvotes: 4

Niklas9
Niklas9

Reputation: 9386

If the only thing that differs is the link, you could of course put it all on one line:

<a href='{% if user.is_authenticated  %}{% url 'vote' %}{% else %}{% url 'login' %}{% endif %}' id='story-vote-{{ story.id }}' class='vote'><img src='{{ STATIC_URL }}images/arrow.gif'></a>

Perhaps it's not ideal since is not as readable as your first suggestion.

However, since you have the url inside your view already, you could set the link inside your view and pass it down to your controller.. example view logic:

link = 'login'
if user.is_authenticated:  link = 'vote'

and in your controller:

<a href='{{ link }}' id='story-vote-{{ story.id }}' class='vote'><img src='{{ STATIC_URL }}images/arrow.gif'></a>

Upvotes: 3

sdkfasldf
sdkfasldf

Reputation: 607

Yes, you pass link as an argument to the template. The variables you apply to a Template is what you call a Context.

The true django way would be to separate logic from representation as much as possible. That's why templates can have if and for-loops, but should certainly avoid variables.

Upvotes: 1

Related Questions