##// END OF EJS Templates
Saving image thumbnails size to the database and using this size in the HTML
neko259 -
r452:308af8e9 1.5-dev
parent child Browse files
Show More
@@ -0,0 +1,92 b''
1 # -*- coding: utf-8 -*-
2 from south.utils import datetime_utils as datetime
3 from south.db import db
4 from south.v2 import SchemaMigration
5 from django.db import models
6
7
8 class Migration(SchemaMigration):
9
10 def forwards(self, orm):
11 # Adding field 'Post.image_pre_width'
12 db.add_column(u'boards_post', 'image_pre_width',
13 self.gf('django.db.models.fields.IntegerField')(default=0),
14 keep_default=False)
15
16 # Adding field 'Post.image_pre_height'
17 db.add_column(u'boards_post', 'image_pre_height',
18 self.gf('django.db.models.fields.IntegerField')(default=0),
19 keep_default=False)
20
21
22 def backwards(self, orm):
23 # Deleting field 'Post.image_pre_width'
24 db.delete_column(u'boards_post', 'image_pre_width')
25
26 # Deleting field 'Post.image_pre_height'
27 db.delete_column(u'boards_post', 'image_pre_height')
28
29
30 models = {
31 'boards.ban': {
32 'Meta': {'object_name': 'Ban'},
33 'can_read': ('django.db.models.fields.BooleanField', [], {'default': 'True'}),
34 u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
35 'ip': ('django.db.models.fields.GenericIPAddressField', [], {'max_length': '39'}),
36 'reason': ('django.db.models.fields.CharField', [], {'default': "'Auto'", 'max_length': '200'})
37 },
38 'boards.post': {
39 'Meta': {'object_name': 'Post'},
40 '_text_rendered': ('django.db.models.fields.TextField', [], {}),
41 u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
42 'image': ('boards.thumbs.ImageWithThumbsField', [], {'max_length': '100', 'blank': 'True'}),
43 'image_height': ('django.db.models.fields.IntegerField', [], {'default': '0'}),
44 'image_pre_height': ('django.db.models.fields.IntegerField', [], {'default': '0'}),
45 'image_pre_width': ('django.db.models.fields.IntegerField', [], {'default': '0'}),
46 'image_width': ('django.db.models.fields.IntegerField', [], {'default': '0'}),
47 'last_edit_time': ('django.db.models.fields.DateTimeField', [], {}),
48 'poster_ip': ('django.db.models.fields.GenericIPAddressField', [], {'max_length': '39'}),
49 'poster_user_agent': ('django.db.models.fields.TextField', [], {}),
50 'pub_time': ('django.db.models.fields.DateTimeField', [], {}),
51 'referenced_posts': ('django.db.models.fields.related.ManyToManyField', [], {'blank': 'True', 'related_name': "'rfp+'", 'null': 'True', 'symmetrical': 'False', 'to': "orm['boards.Post']"}),
52 'text': ('markupfield.fields.MarkupField', [], {'rendered_field': 'True'}),
53 'text_markup_type': ('django.db.models.fields.CharField', [], {'default': "'markdown'", 'max_length': '30'}),
54 'thread': ('django.db.models.fields.related.ForeignKey', [], {'default': 'None', 'to': "orm['boards.Post']", 'null': 'True'}),
55 'thread_new': ('django.db.models.fields.related.ForeignKey', [], {'default': 'None', 'to': "orm['boards.Thread']", 'null': 'True'}),
56 'title': ('django.db.models.fields.CharField', [], {'max_length': '50'}),
57 'user': ('django.db.models.fields.related.ForeignKey', [], {'default': 'None', 'to': "orm['boards.User']", 'null': 'True'})
58 },
59 'boards.setting': {
60 'Meta': {'object_name': 'Setting'},
61 u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
62 'name': ('django.db.models.fields.CharField', [], {'max_length': '50'}),
63 'user': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['boards.User']"}),
64 'value': ('django.db.models.fields.CharField', [], {'max_length': '50'})
65 },
66 'boards.tag': {
67 'Meta': {'object_name': 'Tag'},
68 u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
69 'linked': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['boards.Tag']", 'null': 'True', 'blank': 'True'}),
70 'name': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
71 'threads': ('django.db.models.fields.related.ManyToManyField', [], {'blank': 'True', 'related_name': "'tag+'", 'null': 'True', 'symmetrical': 'False', 'to': "orm['boards.Thread']"})
72 },
73 'boards.thread': {
74 'Meta': {'object_name': 'Thread'},
75 'bump_time': ('django.db.models.fields.DateTimeField', [], {}),
76 u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
77 'last_edit_time': ('django.db.models.fields.DateTimeField', [], {}),
78 'replies': ('django.db.models.fields.related.ManyToManyField', [], {'blank': 'True', 'related_name': "'tre+'", 'null': 'True', 'symmetrical': 'False', 'to': "orm['boards.Post']"}),
79 'tags': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['boards.Tag']", 'symmetrical': 'False'})
80 },
81 'boards.user': {
82 'Meta': {'object_name': 'User'},
83 'fav_tags': ('django.db.models.fields.related.ManyToManyField', [], {'symmetrical': 'False', 'to': "orm['boards.Tag']", 'null': 'True', 'blank': 'True'}),
84 'fav_threads': ('django.db.models.fields.related.ManyToManyField', [], {'blank': 'True', 'related_name': "'+'", 'null': 'True', 'symmetrical': 'False', 'to': "orm['boards.Post']"}),
85 u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
86 'rank': ('django.db.models.fields.IntegerField', [], {}),
87 'registration_time': ('django.db.models.fields.DateTimeField', [], {}),
88 'user_id': ('django.db.models.fields.CharField', [], {'max_length': '50'})
89 }
90 }
91
92 complete_apps = ['boards'] No newline at end of file
@@ -235,10 +235,15 b' class Post(models.Model):'
235 image_width = models.IntegerField(default=0)
235 image_width = models.IntegerField(default=0)
236 image_height = models.IntegerField(default=0)
236 image_height = models.IntegerField(default=0)
237
237
238 image_pre_width = models.IntegerField(default=0)
239 image_pre_height = models.IntegerField(default=0)
240
238 image = thumbs.ImageWithThumbsField(upload_to=_update_image_filename,
241 image = thumbs.ImageWithThumbsField(upload_to=_update_image_filename,
239 blank=True, sizes=(IMAGE_THUMB_SIZE,),
242 blank=True, sizes=(IMAGE_THUMB_SIZE,),
240 width_field='image_width',
243 width_field='image_width',
241 height_field='image_height')
244 height_field='image_height',
245 preview_width_field='image_pre_width',
246 preview_height_field='image_pre_height')
242
247
243 poster_ip = models.GenericIPAddressField()
248 poster_ip = models.GenericIPAddressField()
244 poster_user_agent = models.TextField()
249 poster_user_agent = models.TextField()
@@ -173,8 +173,6 b' blockquote {'
173 min-width: 1px;
173 min-width: 1px;
174 text-align: center;
174 text-align: center;
175 display: table-row;
175 display: table-row;
176
177 height: 150px;
178 }
176 }
179
177
180 .post > .metadata {
178 .post > .metadata {
@@ -171,8 +171,6 b' blockquote {'
171 min-width: 1px;
171 min-width: 1px;
172 text-align: center;
172 text-align: center;
173 display: table-row;
173 display: table-row;
174
175 height: 150px;
176 }
174 }
177
175
178 .post > .metadata {
176 .post > .metadata {
@@ -79,6 +79,8 b''
79 href="{{ thread.op.image.url }}"><img
79 href="{{ thread.op.image.url }}"><img
80 src="{{ thread.op.image.url_200x150 }}"
80 src="{{ thread.op.image.url_200x150 }}"
81 alt="{{ thread.op.id }}"
81 alt="{{ thread.op.id }}"
82 width="{{ thread.op.image_pre_width }}"
83 height="{{ thread.op.image_pre_height }}"
82 data-width="{{ thread.op.image_width }}"
84 data-width="{{ thread.op.image_width }}"
83 data-height="{{ thread.op.image_height }}"/>
85 data-height="{{ thread.op.image_height }}"/>
84 </a>
86 </a>
@@ -154,6 +156,8 b''
154 href="{{ post.image.url }}"><img
156 href="{{ post.image.url }}"><img
155 src=" {{ post.image.url_200x150 }}"
157 src=" {{ post.image.url_200x150 }}"
156 alt="{{ post.id }}"
158 alt="{{ post.id }}"
159 width="{{ post.image_pre_width }}"
160 height="{{ post.image_pre_height }}"
157 data-width="{{ post.image_width }}"
161 data-width="{{ post.image_width }}"
158 data-height="{{ post.image_height }}"/>
162 data-height="{{ post.image_height }}"/>
159 </a>
163 </a>
@@ -227,7 +231,7 b''
227 {% block metapanel %}
231 {% block metapanel %}
228
232
229 <span class="metapanel">
233 <span class="metapanel">
230 <b><a href="{% url "authors" %}">Neboard</a> 1.4.1</b>
234 <b><a href="{% url "authors" %}">Neboard</a> 1.5</b>
231 {% trans "Pages:" %}
235 {% trans "Pages:" %}
232 {% for page in pages %}
236 {% for page in pages %}
233 [<a href="
237 [<a href="
@@ -40,6 +40,8 b''
40 href="{{ post.image.url }}"><img
40 href="{{ post.image.url }}"><img
41 src="{{ post.image.url_200x150 }}"
41 src="{{ post.image.url_200x150 }}"
42 alt="{{ post.id }}"
42 alt="{{ post.id }}"
43 width="{{ post.image_pre_width }}"
44 height="{{ post.image_pre_height }}"
43 data-width="{{ post.image_width }}"
45 data-width="{{ post.image_width }}"
44 data-height="{{ post.image_height }}"/>
46 data-height="{{ post.image_height }}"/>
45 </a>
47 </a>
@@ -3,6 +3,7 b''
3 django-thumbs by Antonio MelΓ©
3 django-thumbs by Antonio MelΓ©
4 http://django.es
4 http://django.es
5 """
5 """
6 from django.core.files.images import ImageFile
6 from django.db.models import ImageField
7 from django.db.models import ImageField
7 from django.db.models.fields.files import ImageFieldFile
8 from django.db.models.fields.files import ImageFieldFile
8 from PIL import Image
9 from PIL import Image
@@ -13,13 +14,13 b' import cStringIO'
13 def generate_thumb(img, thumb_size, format):
14 def generate_thumb(img, thumb_size, format):
14 """
15 """
15 Generates a thumbnail image and returns a ContentFile object with the thumbnail
16 Generates a thumbnail image and returns a ContentFile object with the thumbnail
16
17
17 Parameters:
18 Parameters:
18 ===========
19 ===========
19 img File object
20 img File object
20
21
21 thumb_size desired thumbnail size, ie: (200,120)
22 thumb_size desired thumbnail size, ie: (200,120)
22
23
23 format format of the original image ('jpeg','gif','png',...)
24 format format of the original image ('jpeg','gif','png',...)
24 (this format will be used for the generated thumbnail, too)
25 (this format will be used for the generated thumbnail, too)
25 """
26 """
@@ -41,7 +42,7 b' def generate_thumb(img, thumb_size, form'
41 # crop it
42 # crop it
42 image2 = image.crop(
43 image2 = image.crop(
43 (xnewsize, ynewsize, xsize - xnewsize, ysize - ynewsize))
44 (xnewsize, ynewsize, xsize - xnewsize, ysize - ynewsize))
44 # load is necessary after crop
45 # load is necessary after crop
45 image2.load()
46 image2.load()
46 # thumbnail of the cropped image (with ANTIALIAS to make it look better)
47 # thumbnail of the cropped image (with ANTIALIAS to make it look better)
47 image2.thumbnail(thumb_size, Image.ANTIALIAS)
48 image2.thumbnail(thumb_size, Image.ANTIALIAS)
@@ -160,7 +161,9 b' class ImageWithThumbsField(ImageField):'
160 """
161 """
161
162
162 def __init__(self, verbose_name=None, name=None, width_field=None,
163 def __init__(self, verbose_name=None, name=None, width_field=None,
163 height_field=None, sizes=None, **kwargs):
164 height_field=None, sizes=None,
165 preview_width_field=None, preview_height_field=None,
166 **kwargs):
164 self.verbose_name = verbose_name
167 self.verbose_name = verbose_name
165 self.name = name
168 self.name = name
166 self.width_field = width_field
169 self.width_field = width_field
@@ -168,6 +171,46 b' class ImageWithThumbsField(ImageField):'
168 self.sizes = sizes
171 self.sizes = sizes
169 super(ImageField, self).__init__(**kwargs)
172 super(ImageField, self).__init__(**kwargs)
170
173
174 if sizes is not None and len(sizes) == 1:
175 self.preview_width_field = preview_width_field
176 self.preview_height_field = preview_height_field
177
178 def update_dimension_fields(self, instance, force=False, *args, **kwargs):
179 """
180 Update original image dimension fields and thumb dimension fields
181 (only if 1 thumb size is defined)
182 """
183
184 super(ImageWithThumbsField, self).update_dimension_fields(instance,
185 force, *args,
186 **kwargs)
187 thumb_width_field = self.preview_width_field
188 thumb_height_field = self.preview_height_field
189
190 if thumb_width_field is None or thumb_height_field is None \
191 or len(self.sizes) != 1:
192 return
193
194 original_width = getattr(instance, self.width_field)
195 original_height = getattr(instance, self.height_field)
196
197 if original_width > 0 and original_height > 0:
198 thumb_width, thumb_height = self.sizes[0]
199
200 w_scale = float(thumb_width) / original_width
201 h_scale = float(thumb_height) / original_height
202 scale_ratio = min(w_scale, h_scale)
203
204 if scale_ratio >= 1:
205 thumb_width_ratio = original_width
206 thumb_height_ratio = original_height
207 else:
208 thumb_width_ratio = int(original_width * scale_ratio)
209 thumb_height_ratio = int(original_height * scale_ratio)
210
211 setattr(instance, thumb_width_field, thumb_width_ratio)
212 setattr(instance, thumb_height_field, thumb_height_ratio)
213
171
214
172 from south.modelsinspector import add_introspection_rules
215 from south.modelsinspector import add_introspection_rules
173 add_introspection_rules([], ["^boards\.thumbs\.ImageWithThumbsField"])
216 add_introspection_rules([], ["^boards\.thumbs\.ImageWithThumbsField"])
General Comments 0
You need to be logged in to leave comments. Login now