Django: Why cannot I use the custom file field?

Collapse
X
 
  • Time
  • Show
Clear All
new posts
  • imhomer
    New Member
    • Feb 2012
    • 11

    Django: Why cannot I use the custom file field?

    I have been tortured by this problem for a whole week. I really hope a superman can help me solve it. I tried to create a new file field called "ThumbnailImage Field". The following is my model.py:

    Code:
    from django.db import models
    from django.contrib import admin
    from cn.han import ThumbnailImageField
    from django.db.models.fields.files import ImageField, ImageFieldFile
    # Create your models here.
    
    class Item(models.Model):
        name = models.CharField(max_length=250)
        description = models.TextField()
    
        class Meta:
            ordering = ['name']
    
        def __unicode__(self):
            return self.name
    
        @models.permalink
        def get_absolute_url(self):
            return ('item_detail', None, {'object_id': self.id})
    
    class Photo(models.Model):
        item = models.ForeignKey(Item)
        title = models.CharField(max_length=100)
        image = ThumbnailImageField(upload_to='photos')
        #TypeError here: 'module' object is not callable.
        caption = models.CharField(max_length=250, blank=True)
    
        class Meta:
            ordering = ['title']
    
        def __unicode__(self):
            return self.title
    
        @models.permalink
        def get_absolute_url(self):
            return ('photo_detail', None, {'object_id': self.id})
    
    class PhotoInline(admin.StackedInline):
        model = Photo
    
    class ItemAdmin(admin.ModelAdmin):
        inlines = [PhotoInline]
    
    admin.site.register(Item, ItemAdmin)
    admin.site.register(Photo)
    The following is my ThumnailImageFi eld.py which stored under /cn/han/:

    Code:
    from django.db.models.fields.files import ImageField, ImageFieldFile
    from PIL import Image
    import os
    from django.db import models
    
    def _add_thumb(s):
        """
        Modifies a string (filename, URL) containing an image filename, to insert
        '.thumb' before the file extension (which is changed to be '.jpg').
        """
        parts = s.split(".")
        parts.insert(-1, "thumb")
        if parts[-1].lower() not in ['jpeg', 'jpg']:
            parts[-1] = 'jpg'
        return ".".join(parts)
    
    class ThumbnailImageField(ImageField):
        """
        Behaves like a regular ImageField, but stores an extra (JPEG) thumbnail
        image, providing get_FIELD_thumb_url() and get_FIELD_thumb_filename().
    
        Accepts two additional, optional arguments: thumb_width and thumb_height,
        both defaulting to 128 (pixels). Resizing will preserve aspect ratio while
        staying inside the requested dimensions; see PIL's Image.thumbnail()
        method documentation for details.
        """
        
        def __init__(self, thumb_width=128, thumb_height=128, *args, **kwargs):
            self.thumb_width = thumb_width
            self.thumb_height = thumb_height
            super(ThumbnailImageField, self).__init__(*args, **kwargs)
    
        def _get_path(self):
            self._require_file()
            return self.storage.path(self.name)
        path = property(_get_path)
        
        class ThumbnailImageFieldFile(ImageFieldFile):
            def _get_thumb_path(self):
                return _add_thumb(self.path)
            thumb_path = property(_get_thumb_path)
    
            def _get_thumb_url(self):
                return _add_thumb(self.url)
            thumb_url = property(_get_thumb_url)
    
            def save(self, name, content, save=True):
                super(ThumbnailImageFieldFile, self).save(name, content, save)
                img = Image.open(self.path)
                img.thumbnail(
                    (self.field.thumb_width, self.field.thumb_height),
                    Image.ANTIALIAS
                )
                img.save(self.thumb_path, 'JPEG')
    
            def delete(self, save=True):
                if os.path.exists(self.thumb_path):
                    os.remove(self.thumb_path)
                super(ThumbnailImageFieldFile, self).delete(save)
        attr_class = ThumbnailImageFieldFile
    Finally here is my template called items_list.html :

    Code:
    {% extends "base.html" %}
    
    {% block title %}Item List{% endblock %}
    
    {% block content %}
    
    <p><a href="{% url index %}">&laquo; Back to main page</a></p>
    
    <h2>Items</h2>
    {% if object_list %}
    <table>
        <tr>
            <th>Name</th>
            <th>Sample Thumb</th>
            <th>Description</th>
        </tr>
        {% for item in object_list %}
        <tr>
            <td><i>{{ item.name }}</i></td>
            <td>
                {% if item.photo_set.count %}
                <a href="{{ item.get_absolute_url }}">
                   <img src="{{ item.photo_set.all.0.image.thumb_url }}" />
                </a>
                {% else %}
                (No photos currently uploaded)
                {% endif %}
            </td>
            <td>{{ item.description }}</td>
        </tr>
        {% endfor %}
    </table>
    {% else %}
    <p>There are currently no items to display.</p>
    {% endif %}
    
    {% endblock %}
Working...