If you just want to have a clean working solution, have a look at django-photologue (http://code.google.com/p/django-photologue/). It is amazing, and really easy to integrate well. Also have a look at sorl-thumbnail (http://code.google.com/p/sorl-thumbnail/).
If you want to write your own code and make it a bit cleaner, I think you should first try to break things a bit more (http://en.wikipedia.org/wiki/Separation_of_concerns). For example, having different picture sizes is a presentation problem, not a persistence problem. So if you solve the that in a template tag, it will probably be much cleaner. Just my own 2 cents ... and yes, I know that I didnt really answer your question ... sorry Good luck ! 2008/8/29 drbig <[EMAIL PROTECTED]>: > > Hi! > > Before I paste the code here is what I want to achieve: > 1) All content is supplied via django admin, no custom upload/edit > forms > 2) The Photo class holds title and note (the text data), two images > (full and thumb), and stats data of hits and comments count > 3) The stamp should be updated only when the text data or full image > change (only full as...) > 4) When image is uploaded it should be resized if too large and the > thumbnail should be auto(re)generated > > Here is the code: > from django.db import models > from django.conf import settings > from PIL import Image > from datetime import datetime as dt > import md5, time, os > > class Tag(models.Model): > stamp = models.DateTimeField(auto_now = True) > name = models.CharField(max_length = 32) > > class Meta: > ordering = ['name'] > get_latest_by = '-stamp' > > def __unicode__(self): > return self.name > > class Photo(models.Model): > stamp = models.DateTimeField(auto_now_add = True) > title = models.CharField(max_length = 255) > note = models.TextField() > content_hash = models.CharField(max_length = 32, editable = False) > upload_image = models.ImageField(upload_to = 'photos/tmp', blank = > True) > ifull = models.CharField(max_length = 128, editable = False) > ithumb = models.CharField(max_length = 128, editable = False) > image_hash = models.CharField(max_length = 32, editable = False) > hits = models.PositiveIntegerField(default = 0, editable = False) > comments_count = models.PositiveIntegerField(default = 0, editable = > False) > tags = models.ManyToManyField(Tag) > > class Meta: > ordering = ['-stamp'] > get_latest_by = '-stamp' > > def __unicode__(self): > return self.title > > def save(self): > try: > new_hash = > md5.new(self.upload_image.read(num_bytes = 1024)).hexdigest() > if new_hash != self.image_hash: > if self.ifull: > name = self.ifull.split('/') > [-1] > else: > name = str(int(time.time())) + > '.jpg' > img = > Image.open(self.upload_image.path) > img.load() > self.upload_image.delete(save = False) > if img.size > (800, 600): > img.thumbnail((800, 600), > Image.ANTIALIAS) > img.save(settings.MEDIA_ROOT + 'photos/ > full/' + name, 'jpeg') > img.thumbnail((128, 128), > Image.ANTIALIAS) > img.save(settings.MEDIA_ROOT + 'photos/ > thumb/' + name, 'jpeg') > self.ifull = '/data/photos/full/' + > name > self.ithumb = '/data/photos/thumb/' + > name > self.image_hash = new_hash > self.stamp = dt.now() > except Exception, e: > pass > new_hash = md5.new(self.title + self.note).hexdigest() > if new_hash != self.content_hash: > self.content_hash = new_hash > self.stamp = dt.now() > super(Photo, self).save() > > def delete(self): > if self.ifull: > name = self.ifull.split('/')[-1] > try: > os.remove(settings.MEDIA_ROOT + > 'photos/thumb/' + name) > os.remove(settings.MEDIA_ROOT + > 'photos/full/' + name) > except Exception, e: > pass > super(Photo, self).delete() > > class Comment(models.Model): > stamp = models.DateTimeField(auto_now_add = True) > ip = models.IPAddressField() > signature = models.CharField(max_length = 64) > content = models.TextField() > photo = models.ForeignKey(Photo) > > class Meta: > ordering = ['-stamp'] > get_latest_by = '-stamp' > > def __unicode__(self): > return self.content > > def save(self): > self.photo.comments_count += 1 > self.photo.save() > super(Comment, self).save() > > def delete(self): > self.photo.comments_count -= 1 > self.photo.save() > super(Comment, self).delete() > > As you can see, I'm using a temporary filed for image upload and > (hackish) code to make the thumbnail and generate urls, delete files > when removing, update the stamp only when necessary etc... > > At first I was trying to use two ImageFields, so the uploaded image > will be the full image (resized if necessary), and the thumb generated > from the full image, but it is impossible to assign to an empty > ImageField anything that works right, and the .url attribute never > worked okey (the best i got was upload_to + filename). I have static > files served from another url ('/data' as you should figure out from > the code). > > I think that it would be nice if i could do something like that: > 1) full_image is ImageField with uploaded image, upload_to='photos/ > full' > 2) thumb_image is an empty ImageFIeld, upload_to='photos/thumb') > 3) they both have somehow set base_url to '/data', so for example > full_image.url should be '/data/photos/full/name' (base_url + > upload_to + filename) > img = Image.open(full_image.path) > if img.size > (800, 600): > img.thumbnail((800, 600), Image.ANTIALIAS) > img.save(full_image.file, 'jpeg') # this is _really_ what it should > work like.... :S > full_image.rename(_generated_name_) > thumb_image.new(_generated_name_) # creates a file in the directory > it's already assigned to, as when uploading... > img.thumbnail((128, 128), Image.ANTIALIAS) > img.save(thumb_image.file, 'jpeg') > # DONE! > and now: > full_image.url -> '/data/photos/full/_generated_name_' (base_url + > upload_to + filename) > full_image.path -> '/mediaroot/photos/full/ > _generated_name_' (media_root + upload_to + filename) > > Huh, I hope you understand what I have on mind... Any ideas how to > make my code cleaner will be appreciated! :) > > > > -- Jabber : [EMAIL PROTECTED] Skype : Guillaume.Lederrey Projects : * http://rwanda.ledcom.ch/ * http://trock.ch/ Others : * http://kiva.org/ --~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "Django users" group. To post to this group, send email to django-users@googlegroups.com To unsubscribe from this group, send email to [EMAIL PROTECTED] For more options, visit this group at http://groups.google.com/group/django-users?hl=en -~----------~----~----~----~------~----~------~--~---