2

I'm trying to concatenate two numbers to pass as a parameter to an included template.

In particular, in the code below, I'm trying to pass something in for "divnum"

I looked at: How can I concatenate forloop.counter to a string in my django template

and figured that the code below would work, but it's still adding like numbers! (E.g., I'm getting "2" where I want "11")

<div id="{{ forloop.counter }}graph" style="display:none; padding:  1em, 0;margin: 1em, 0;">
{% with x=forloop.counter|stringformat:"s" %}
    {% include 'graph-div.html' with divnum="1"|stringformat:"s"|add:x width="50%" question=response.question title="Nationwide" %}
{% endwith %}
</div>

How do I concatenate these numbers as strings?

There's a Warning in the docs that says: Strings that can be coerced to integers will be summed, not concatenated, as in the first example above.

so can I not do it at all? Seems like if there's a warning for it, then they know it's an issue, and there should be a solution out there somewhere...

Community
  • 1
  • 1
Colleen
  • 23,899
  • 12
  • 45
  • 75
  • 1
    It's not an issue, it's just how python works, and given that the template filters are parsed left to right, you are setting a number (1), converting it to a string ("1") and adding your forloop counter to it, giving you a single integer. This kind of complicated logic in the template might be better suited to a template tag if possible (or done in the view) – Timmy O'Mahony Feb 15 '12 at 23:53
  • I suppose by "issue" I mean "something that programmers want to do that they can't do". I try to avoid doing small stuff like this in the view, as it increases the complexity for (what I deem) a poor reason, but sounds like I'll have to, or find another workaround. – Colleen Feb 15 '12 at 23:56
  • Sounds like a good cause for a template tag or filter. It will also make things easier to read and maintain in the future. What exactly are you trying to do in the code and what's in the included template? – Timmy O'Mahony Feb 15 '12 at 23:58
  • I'm basically just trying to assign distinct ids-- so I have a number of "graph" divs, each of which has two "chart" divs inside them (the content of the included file). I have a function that renders graphs and takes an id of the div to render to. A coworker pointed out that since they just need to be distinct, that I could use "a1" instead of "11", so that's what I'm doing now. – Colleen Feb 16 '12 at 00:05
  • have you got actual `Chart` objects? If so you can simply use their primary keys as distinct id's for your css as they will always be distinct: `
    `
    – Timmy O'Mahony Feb 16 '12 at 00:51
  • if only... nope, I'm creating chart objects from data. Good idea, though! – Colleen Feb 16 '12 at 01:45
  • "I try to avoid doing small stuff like this in the view" --- That's the exactly opposite way to look at it. The template should have as little logic as possible in it. You should be moving as much as possible out of the template and into the view (or model), not the other way around (within reason). – Chris Pratt Feb 21 '12 at 22:35

2 Answers2

1

Define your own concatenate template filter in <appname>\templatetags\<appname>_extras.py

from django import template

register = template.Library()

@register.filter
def concatenate(arg1, arg2):
    """concatenate arg1 & arg2"""
    return str(arg1) + str(arg2)
user
  • 17,781
  • 20
  • 98
  • 124
0

Following the Model-View-Template (MVT) paradigm of Django, the logic setting up the data layer for the user interface to display should be in the view layer. I know this isn't business logic, per se, but it seems like something better handled in the view. As a rule of thumb, I make sure my templates do next to no logic, other than the basic display-based decisions. Since you are "...creating chart objects from data," you should also generate your unique ids alongside the data objects as they are created/assembled in the view. A template tag would also get you through the problem, but I would still suggest putting this in the view. Have all of your data complete in the view before you hand it to the template.

Furbeenator
  • 8,106
  • 4
  • 46
  • 54