Django:为什么我不能使用自定义文件字段?
我被这个问题折磨了整整一周。我真的希望超人能帮我解决这个问题。我试图创建一个名为"ThumbnailImageField"的新文件字段。以下是我的模型.py:
选择 | 换行 | 行号
- 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)
下面是我的ThumnailImageField。py存储在/cn/han/下:
选择 | 换行 | 行号
- 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
最后是我的模板items_list.html:
选择 | 换行 | 行号
- {% extends "base.html" %}
- {% block title %}Item List{% endblock %}
- {% block content %}
- <p><a href="{% url index %}">« 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 %}