Django:为什么我不能使用自定义文件字段?

我被这个问题折磨了整整一周。我真的希望超人能帮我解决这个问题。我试图创建一个名为"ThumbnailImageField"的新文件字段。以下是我的模型.py:

选择 | 换行 | 行号
  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.  

下面是我的ThumnailImageField。py存储在/cn/han/下:

选择 | 换行 | 行号
  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.  

最后是我的模板items_list.html:

选择 | 换行 | 行号
  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 %}

标签: python

添加新评论