TDL
TDL

Reputation: 49

Trouble Rendering Template Variables in Django

I am hitting a brick wall when it comes to solving this problem. I have a template that is being included in an other template, but I am unable to render any template variables in the included template. I have a separate template tag file for the included template. I am at a total loss right now how to resolve this problem.

I would like to be able to render the field values from my model in the template (which consist of an image, a short description, etc.) I am fairly certain that I am going about this in the wrong way.

Below is my code:

The model:

class AddOnItem(models.Model):
    base_product = models.ForeignKey(Product)
    base_price = models.DecimalField(max_digits=8, decimal_places=2, default=0.0)
    addon_image = models.ImageField(upload_to='uploads/shop/product/images/', 
            default='uploads/shop/product/images/', help_text='Max width: 450px')
    short_description = models.CharField(max_length=255, blank=True)

    def __unicode__(self):
        return self.base_product.name

The template:

{% load addon_tags %}
{% if items_to_add %}
  {% for items in items_to_add %}
  <div id="addon-container">
    <div id="left-addon" class="addon-container">
        <a href=""><img src="#" class="addon-image"></a>
        <p class="addon-description">{{items.short_description}}</p>
    </div>
  </div>
  {% endfor %}
 {% endif %}

addon_tags.py:

from django import template

from sho.models import AddOnItem

register = template.Library()


@register.inclusion_tag("foo/templates/v/sho/addon.html", takes_context=True)
def add_on_render():
    context['items_to_add'] = AddOnItem()

    return context

I imagine I am doing either a lot wrong (my assumption at the moment) or I am missing some minor bit. I have been working on this for several days and have gone over the docs repeatedly. I am simply completely missing something and this has become a major blocker for me. Any help would be appreciated.

Django version 1.4

Edit: I ended up rewriting the view and did away with the templatetag. Thanks to both Daniel Roseman and Odif Yltsaeb for their replies.

Upvotes: 1

Views: 104

Answers (3)

Fibio
Fibio

Reputation: 151

if you set "takes_context=True" you should take context as the first argument in decorated function:

@register.inclusion_tag("foo/templates/v/sho/addon.html", takes_context=True)
def add_on_render(context):
    context['items_to_add'] = AddOnItem()
    ....

Upvotes: 0

Daniel Roseman
Daniel Roseman

Reputation: 599530

You haven't posted the template that you are attempting to include the tag in. I suspect you're not calling it at all, because there are a couple of errors that would cause exceptions if you did try and use the tag. You need to do {% add_on_render %} somewhere in your main template.

As I say though there are a couple of errors. Firstly, you don't define context (as an empty dict) before adding the items_to_add key. You can shortcut this by just doing it in one go.

Secondly you've made items_to_add a single, blank, AddOnItem. So in your included template, iterating through items_to_add does nothing at all. Not sure what you are trying to do there. Perhaps you want to pass all AddOnItem instances?

context = {'items_to_add':  AddOnItem.objects.all()}

Or maybe you want to filter them by some criteria, in which case you probably want to pass those criteria to the inclusion tag itself:

def add_on_render(product):
    context = {'items_to_add':  AddOnItem.objects.filter(base_product=product)}

and you would call it from the main template like this:

{% add_on_render my_product %}

Upvotes: 1

Odif Yltsaeb
Odif Yltsaeb

Reputation: 5656

1) From your post you are adding empty, new item into the context in add_on_render templateag.

2) I cant see in your post, WHERE you are using {% add_on_render %} templatetag. You have created templattag, but do not seem to be using it anywhere.

It is bit hard to understand what exactly are you trying to do or why you even need templatetag there.

If you want to display models field value, you do not need templateag for this and all the stuff that you show in your "template" part of this post, could be very well in your main template, which i assume, is not shown in your post.

If you want to use templatetag, then this templatetag should probably recieve AddOnItem istance as parameter like this:

@register.inclusion_tag("foo/templates/v/sho/addon.html", takes_context=True)
def add_on_render(item):
    context['items_to_add'] = item

    return context

And You could use it in some template like this:

{% load addon_tags %}
{% if items_to_add %}
  {% for items in items_to_add %}
  <div id="addon-container">
    <div id="left-addon" class="addon-container">
        <a href=""><img src="#" class="addon-image"></a>
        <p class="addon-description">{% add_on_render items %}</p>
    </div>
  </div>
  {% endfor %}
 {% endif %}

and your foo/templates/v/sho/addon.html would like like this:

{{ items_to_add.short_description }}

But doing it this way seems very unnecessary as you could achieve all that without templatag by using the template code that you already have outside your "main" template.

Upvotes: 1

Related Questions