Udders
Udders

Reputation: 6986

Function not being called in Python, why? and how can I solve it?

I am currently working on python/django site, at the moment I have a template that looks like this

 {% extends "shopbase.html" %}
{% block pageid %}products{% endblock %}
{% block right-content %}

<img src="{{MEDIA_URL}}/local/images/assets/products.png" alt="Neal and Wolf News" class="position"/>
    <div class="products">
    <form method="post" action="{% url category category.slug %}">
    {% for product in category.products.all %}
        <div class="{% cycle 'clear' '' '' %}">
            <img src="{{MEDIA_URL}}{{download.mini.thumbnail}}" alt="{{product.name}}" class="thumbnail"/>
            <h3><a href="{% url shop.views.product category.slug product.slug %}">{{ product.product_type_name }}</a></h3>
            <p class="strap">{{ product.product_sub_name }}</p>
            <p>{{ product.strap }}</p>
            <ul class="clear">
                <li class="price"><b>&pound;{{product.price}}</b></li>
                <li class="quantity">
                    <select name="quantity_{{product.id}}">
                        <option label="1" value="1">1</option>
                        <option label="2" value="2">2</option>
                        <option label="3" value="3">3</option>
                        <option label="4" value="4">4</option>
                        <option label="5" value="5">5</option>
                        <option label="6" value="6">6</option>
                        <option label="7" value="7">7</option>
                        <option label="8" value="8">8</option>
                        <option label="9" value="9">9</option>
                    </select>
                </li>
                <li><b><a href="details">Details &gt;</a></b></li>
                <li><input type="submit" name="add_to_basket_{{product.id}}" value="Add to Basket &gt;"/></a></li>
            </ul>
        </div>
    {% endfor %}
    </form>
    </div>
{% endblock %}

and in the model I have a class that looks like this

def get_thumbnail(self, dimension, on=RES_X, use=USE_BOTH):
    """
    Generate a thumbnail image for this Store Object. The thumbnail will be
    of size 'dimension' on the axis specified by the on parameter (which is
    deduced from calling x_or_y). If the use parameter is set to USE_BOTH
    then the thumbnail will take priority in the generation order. In other
    words, the function checks for the existance of an uploaded thumbnail.
    If one exists, it will use that, otherwise the image field is used
    instead. Specifying either USE_IMAGE or USE_THUMBNAIL here will force
    the generation to a particular asset.
    The image is saved out as a jpeg with the quality set to 90. The
    path relative to the MEDIA_ROOT is then returned.
    """
    from PIL import Image
    import os

    if self.thumbnail and use != StoreObject.USE_IMAGE:
      source_path = str(self.thumbnail)
    elif self.image and use != StoreObject.USE_THUMBNAIL:
      source_path = str(self.image)
    else:
      return ""

    try:
      against = StoreObject.x_or_y(on)
    except KeyError:
      return ""

    target_path = os.path.join(StoreObject.GENERATED_THUMB_LOCATION, "%s-%d%s.png" % (self.slug, dimension, against))

    savepath = os.path.join(settings.MEDIA_ROOT, target_path)
    loadpath = os.path.join(settings.MEDIA_ROOT, source_path)

    if os.path.exists(savepath) and os.path.getmtime(savepath) > os.path.getmtime(loadpath):
      return target_path

    try:
      img = Image.open(loadpath)
    except IOError:
      return ""

    aspect = float(img.size[0]) / float(img.size[1])
    if against == StoreObject.RES_X:
      height = dimension / aspect
      width = dimension
    elif against == StoreObject.RES_Y:
      width = dimension * aspect
      height = dimension

    img = img.resize((width,height), Image.ANTIALIAS)

    img.convert('RGBA').save(savepath, "PNG")
    return target_path

def mini_thumbnail(self):
    """
    Generate and return the path to, a thumbnail that is 50px high
    """
    return self.get_thumbnail(50, "x")

def preview_image(self):
    """
    Generate and return the path to, a thumbnail that is 300px wide, build
    from the image field
    """
    return self.get_thumbnail(300, use=StoreObject.USE_IMAGE)

def preview_thumbnail(self):
    """
    Generate and return the path to, a thumbnail that is 300px wide, build
    from the thumbnail field
    """
    return self.get_thumbnail(300, use=StoreObject.USE_THUMBNAIL)

Now as you can see I am trying to pull out of the database some information on a certain item, and show an image of that item in a thumbnail which generated from the thumbnail function above (in the template I using product.mini_thumbnail however there seems to be know image? however if I print product.image with my MEDIA_URL then I get the fullsized image. Can anyone suggest what might be happening?

Upvotes: 0

Views: 329

Answers (2)

Henrik Joreteg
Henrik Joreteg

Reputation: 1736

As with many things in Django... someone has already solved this problem and come up with a clean, flexible solution for generating/storing thumbnails of different sizes etc. I'd strongly suggest looking at the sorl-thumbnail project.

Docs here: http://thumbnail.sorl.net/docs/

Downloads here: http://code.google.com/p/sorl-thumbnail/downloads/list

Upvotes: 5

Daniel Roseman
Daniel Roseman

Reputation: 599778

Your template has {{download.mini.thumbnail}} instead of {{download.mini_thumbnail}}

Upvotes: 2

Related Questions