chuse
chuse

Reputation: 383

How to pass an url tag in a custom template tag?

I'm learning Django building a small site, and I found that I have many templates where I list objects, each of them with a link to it. I thought I could make a custom template tag, something like

{% object_list some %}

some is a dictionary {'list': obj_list, 'link': link} where obj_list is the list of objects I want to print out and link should some url structure that points to the item.

The template (called object_list.html) should look like

{% for object in object_list %}
    <li><a href="{% url myapp:object object.id %}">{{object.name}}</a></
{% endfor %}

Now, my problem is that I don't know what to do in the url. I want it to be flexible, such that 'myapp:object' is replaced by the argument 'link', for example, if the object type is User, then I use {%url myapp:user user.id%}.

It is possible to do this? How?

I tried this solution, in the form

{% for object in object_list %}
    {% url 'link' as my_url %}
    <li><a href="{% url my_url object.id %}">{{object.name}}</a></li>
{% endfor %}

giving 'myapp:myobject' as argument but it does not work. To be precise, in the template

{% load property_extras %}
{% object_list property_dict %}

where property_dict is my argument, and templatetag/property_extras.py is the file where the tag is saved, gives a NoReverseMatch error (if I use the normal template -without the custom tag- it works fine).

For more information, my template tag is

@register.inclusion_tag('properties/object_list.html')
def object_list(object_dict):
    print(object_dict['list'])
    print(object_dict['link'])
    return {
        'object_list': object_dict['list'],
        'link': object_dict['link'],
        }

Upvotes: 1

Views: 1142

Answers (2)

Jorge Leitao
Jorge Leitao

Reputation: 20173

I believe you can use

{% for object in object_list %}
    <li><a href="{{ object.get_absolute_url }}">{{object.name}}</a></li>
{% endfor %}

and remove the usage of {% url %} altogether. Defining the method get_absolute_url for your model is the recommended way of solving the problem according to the documentation.

Upvotes: 4

Alasdair
Alasdair

Reputation: 309089

Using {% url 'link' as my_url %} doesn't work because you are using the literal string 'link', and you have not included the object id. Do you mean:

{% url link object.id as my_url %}

It's not clear why you save the result to my_url, because you don't use my_url anywhere. Maybe you want the next line to be:

<a href="{{ my_url }}">{{object.name}}</a></li>

However, I don't think you really need as my_url here. It silently swallows errors, which you probably don't want. It would be simpler to do:

<a href="{% url link object.id as my_url %}">{{object.name}}</a></li>

Upvotes: 2

Related Questions