Ben
Ben

Reputation: 970

Unique HTML element IDs for each model with Django

I've got django models displaying on a page using a checkbox input that has a label over it like so:

{% if recipes_list %}
<table>
{% for r in recipes_list %}
<tr>
  <td>
    <section class="ac-container">
      <div>
        <input id="ac-1" type="checkbox" />
        <label for="ac-1">{{r.name}}</label>
        <article class="ac-small">
        <ul>
        {% for i in r.ingredient_list%}
          <li>{{i.part}}, {{i.amount}}</li>
        {% endfor %}
        </ul>
        </article>
      </div>
    </section>
 </td>
</tr>
{% endfor %}
</table>

When I click on the label of each entry in recipes_list, it obviously always opens the article of the first one. I've been looking around for solutions for the past couple days on how to give a unique id in the html for each model entry, but I can't find anything that works with this situation. I've tried forms, model forms, various javascript, and php. How can I do this?

Upvotes: 3

Views: 3620

Answers (3)

karthikr
karthikr

Reputation: 99640

You can write a filter which gets the model name

from django import template
register = template.Library()

@register.filter(name='class_name')
def class_name(obj):
  return obj.__class__.__name__

and in the template:

and in the template, wherever you want the id/classname:

<article id={{obj|class_name}}>
  {# further code #}
</article>

OR

class MyModel(models.Model):
    #fields

    def class_name(self):
        return "%s"%self.__class__.__name__ #returns the model instance name

If you want to return the instance name:

from django.template.defaultfilters import slugify
class MyModel(models.Model):
    def class_name(self):
        return "%s"%(slugify(self.name)) #or whatever field has the specific instance name

and in the template:

{{obj.class_name}}

Upvotes: 3

Aamir Rind
Aamir Rind

Reputation: 39659

Its simple use object primary key as id because its unique (unless you have another loop from another model):

{% for r in recipes_list %}
    <input id="ac-{{ r.id }}" type="checkbox" />
{% endfor %}

Or use forloop.counter:

{% for r in recipes_list %}
    <input id="ac-{{ forloop.counter }}" type="checkbox" />
{% endfor %}

Upvotes: 3

Paulo Bu
Paulo Bu

Reputation: 29804

You can use the forloop.counter to achieve this:

{% if recipes_list %}
<table>
{% for r in recipes_list %}
<tr>
  <td>
    <section class="ac-container">
      <div>
        <input id="ac-{{forloop.counter}}" type="checkbox" />
        <label for="ac-{{forloop.counter}}">{{r.name}}</label>
        <article id="article-{{forloop.counter}}" class="ac-small">
        <ul>
        {% for i in r.ingredient_list%}
          <li>{{i.part}}, {{i.amount}}</li>
        {% endfor %}
        </ul>
        </article>
      </div>
    </section>
 </td>
</tr>
{% endfor %}
</table>

Hope this helps!

Upvotes: 5

Related Questions