paulvs
paulvs

Reputation: 12053

Evaluate string as template tag - Django

I have a Django template which includes a template tag that takes a variable (shop.id) and returns one of two string depending on whether the shop is in a database model, like this

{% is_shop_claimed shop.id %}

The two possible strings returned by the template tag are

return '<p>Taken</p>'

or

return '<a href="/claim_shop/{{shop.id}}/">Claim shop now</a>'

When the code is run, if the second string is returned, it appears in the template (viewing the page source in the browser) like

<a href="/claim_shop/{{shop.id}}/">Claim shop now</a>

and appears in the browser as a link like this

Claim shop now

The problem is that shop.id in the href is not evaluated to a number by the Django template engine.

The link should appear like this for shop 123, for example

<a href="/claim_shop/123/">Claim shop now</a>

I've checked the Django docs for filters to apply to the string in the template tag or in the template so that the string is not escaped but no luck.

I have looked at this but it seems there should be a simple way making the {{shop.id}} evaluated in the template.

I have also made the template tag to return a Bool instead of the two strings, leaving the presentation in the template like I would prefer, but using an if statement around a template tag like this

{% if is_shop_claimed shop.id %}
    <p>Taken</p>
{% elif not is_shop_claimed shop.id %}
    <a href="/claim_shop/{{shop.id}}/">Claim shop now</a>
{% endif %}

doesn't work because I can't put the template tag inside the if statement.

Any suggestions on how to get {{shop.id}} to be evaluated to a number? Any help would be appreciated. I'm learning Django and Python and I have spend hours on this problem.

Upvotes: 2

Views: 1861

Answers (2)

Martin Thurau
Martin Thurau

Reputation: 7654

I suggest you add an is_claimed property to you shop model:

class Shop(models.model):

    # you fields are here

    @property
    def is_claimed(self):
        # logik for determining if the shop is claimed
        if claimed:
            return True
        else:
            return False

Then you can use is in you template:

{% if shop.is_claimed %}
    <p>Taken</p>
{% else %}
    <a href="/claim_shop/{{shop.id}}/">Claim shop now</a>
{% endif %}

You could even move this to a snippet which you can include as need or (to go even further) create an inclusion tag for it.

Upvotes: 1

Ignacio Vazquez-Abrams
Ignacio Vazquez-Abrams

Reputation: 799520

You're being passed the value, so just substitute it in.

return '<a href="/claim_shop/%s/">Claim shop now</a>' % (shop_id,) # or however you refer to it in the code

Upvotes: 3

Related Questions