By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
464,688 Members | 1,159 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 464,688 IT Pros & Developers. It's quick & easy.

Django: Why cannot I use the custom file field?

P: 11
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 "ThumbnailImageField". The following is my model.py:

Expand|Select|Wrap|Line Numbers
  1. from django.db import models
  2. from django.contrib import admin
  3. from cn.han import ThumbnailImageField
  4. from django.db.models.fields.files import ImageField, ImageFieldFile
  5. # Create your models here.
  6.  
  7. class Item(models.Model):
  8.     name = models.CharField(max_length=250)
  9.     description = models.TextField()
  10.  
  11.     class Meta:
  12.         ordering = ['name']
  13.  
  14.     def __unicode__(self):
  15.         return self.name
  16.  
  17.     @models.permalink
  18.     def get_absolute_url(self):
  19.         return ('item_detail', None, {'object_id': self.id})
  20.  
  21. class Photo(models.Model):
  22.     item = models.ForeignKey(Item)
  23.     title = models.CharField(max_length=100)
  24.     image = ThumbnailImageField(upload_to='photos')
  25.     #TypeError here: 'module' object is not callable.
  26.     caption = models.CharField(max_length=250, blank=True)
  27.  
  28.     class Meta:
  29.         ordering = ['title']
  30.  
  31.     def __unicode__(self):
  32.         return self.title
  33.  
  34.     @models.permalink
  35.     def get_absolute_url(self):
  36.         return ('photo_detail', None, {'object_id': self.id})
  37.  
  38. class PhotoInline(admin.StackedInline):
  39.     model = Photo
  40.  
  41. class ItemAdmin(admin.ModelAdmin):
  42.     inlines = [PhotoInline]
  43.  
  44. admin.site.register(Item, ItemAdmin)
  45. admin.site.register(Photo)
  46.  
The following is my ThumnailImageField.py which stored under /cn/han/:

Expand|Select|Wrap|Line Numbers
  1. from django.db.models.fields.files import ImageField, ImageFieldFile
  2. from PIL import Image
  3. import os
  4. from django.db import models
  5.  
  6. def _add_thumb(s):
  7.     """
  8.     Modifies a string (filename, URL) containing an image filename, to insert
  9.     '.thumb' before the file extension (which is changed to be '.jpg').
  10.     """
  11.     parts = s.split(".")
  12.     parts.insert(-1, "thumb")
  13.     if parts[-1].lower() not in ['jpeg', 'jpg']:
  14.         parts[-1] = 'jpg'
  15.     return ".".join(parts)
  16.  
  17. class ThumbnailImageField(ImageField):
  18.     """
  19.     Behaves like a regular ImageField, but stores an extra (JPEG) thumbnail
  20.     image, providing get_FIELD_thumb_url() and get_FIELD_thumb_filename().
  21.  
  22.     Accepts two additional, optional arguments: thumb_width and thumb_height,
  23.     both defaulting to 128 (pixels). Resizing will preserve aspect ratio while
  24.     staying inside the requested dimensions; see PIL's Image.thumbnail()
  25.     method documentation for details.
  26.     """
  27.  
  28.     def __init__(self, thumb_width=128, thumb_height=128, *args, **kwargs):
  29.         self.thumb_width = thumb_width
  30.         self.thumb_height = thumb_height
  31.         super(ThumbnailImageField, self).__init__(*args, **kwargs)
  32.  
  33.     def _get_path(self):
  34.         self._require_file()
  35.         return self.storage.path(self.name)
  36.     path = property(_get_path)
  37.  
  38.     class ThumbnailImageFieldFile(ImageFieldFile):
  39.         def _get_thumb_path(self):
  40.             return _add_thumb(self.path)
  41.         thumb_path = property(_get_thumb_path)
  42.  
  43.         def _get_thumb_url(self):
  44.             return _add_thumb(self.url)
  45.         thumb_url = property(_get_thumb_url)
  46.  
  47.         def save(self, name, content, save=True):
  48.             super(ThumbnailImageFieldFile, self).save(name, content, save)
  49.             img = Image.open(self.path)
  50.             img.thumbnail(
  51.                 (self.field.thumb_width, self.field.thumb_height),
  52.                 Image.ANTIALIAS
  53.             )
  54.             img.save(self.thumb_path, 'JPEG')
  55.  
  56.         def delete(self, save=True):
  57.             if os.path.exists(self.thumb_path):
  58.                 os.remove(self.thumb_path)
  59.             super(ThumbnailImageFieldFile, self).delete(save)
  60.     attr_class = ThumbnailImageFieldFile
  61.  
Finally here is my template called items_list.html:

Expand|Select|Wrap|Line Numbers
  1. {% extends "base.html" %}
  2.  
  3. {% block title %}Item List{% endblock %}
  4.  
  5. {% block content %}
  6.  
  7. <p><a href="{% url index %}">&laquo; Back to main page</a></p>
  8.  
  9. <h2>Items</h2>
  10. {% if object_list %}
  11. <table>
  12.     <tr>
  13.         <th>Name</th>
  14.         <th>Sample Thumb</th>
  15.         <th>Description</th>
  16.     </tr>
  17.     {% for item in object_list %}
  18.     <tr>
  19.         <td><i>{{ item.name }}</i></td>
  20.         <td>
  21.             {% if item.photo_set.count %}
  22.             <a href="{{ item.get_absolute_url }}">
  23.                <img src="{{ item.photo_set.all.0.image.thumb_url }}" />
  24.             </a>
  25.             {% else %}
  26.             (No photos currently uploaded)
  27.             {% endif %}
  28.         </td>
  29.         <td>{{ item.description }}</td>
  30.     </tr>
  31.     {% endfor %}
  32. </table>
  33. {% else %}
  34. <p>There are currently no items to display.</p>
  35. {% endif %}
  36.  
  37. {% endblock %}
Mar 30 '12 #1
Share this question for a faster answer!
Share on Google+

Post your reply

Sign in to post your reply or Sign up for a free account.