From 3961e2bdfa2cb946f1bd367c9a7a392528bbaeef Mon Sep 17 00:00:00 2001 From: Weitian LI Date: Tue, 24 Jun 2014 17:11:44 +0800 Subject: Splited storage function from account.extra * Splited storage function from account.extra -> tools/storage.py - OverwriteStorage - file_cleanup * Updated account.models, archive.models * Added OverwriteStorage and file_cleanup function to notice.models --- account/extra.py | 53 ------------------------------------------------ account/models.py | 3 ++- archive/models.py | 7 ++----- notice/models.py | 12 +++++++++-- tools/storage.py | 60 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 5 files changed, 74 insertions(+), 61 deletions(-) create mode 100644 tools/storage.py diff --git a/account/extra.py b/account/extra.py index d0f74f2..c75ce1c 100644 --- a/account/extra.py +++ b/account/extra.py @@ -6,16 +6,11 @@ Extra models for app account from django import forms from django.db import models -from django.db.models.fields.files import FieldFile -from django.core.files.storage import FileSystemStorage -from django.conf import settings from django.template.defaultfilters import filesizeformat from django.utils.translation import ugettext_lazy as _ from south.modelsinspector import add_introspection_rules -import os - ### custom fields ### class ContentTypeRestrictedFileField(models.FileField): @@ -70,51 +65,3 @@ add_introspection_rules([ ], ["^account\.extra\.ContentTypeRestrictedFileField"]) -### OverwriteStorage ### -class OverwriteStorage(FileSystemStorage): - """ - overwrite original file before store the new one - """ - def get_available_name(self, name): - """ - Returns a filename that's free on the target storage system, - and available for new content to be written to. - Ref: http://djangosnippets.org/snippets/976/ - - This file storage solves overwrite on upload problem. Another - proposed solution was to override the save method on the model - like so (from https://code.djangoproject.com/ticket/11663): - - def save(self, *args, **kwargs): - try: - this = MyModelName.objects.get(id=self.id) - if this.MyImageFieldName != self.MyImageFieldName: - this.MyImageFieldName.delete() - except: pass - super(MyModelName, self).save(*args, **kwargs) - """ - # If the filename already exists, - # remove it as if it was a true file system - if self.exists(name): - filepath = os.path.join(settings.MEDIA_ROOT, name) - if os.path.isfile(filepath): - os.remove(filepath) - return name - - -### delete files associated with model FileField -# Pre-delete signal function for deleting files a model -# https://djangosnippets.org/snippets/2820/ -def file_cleanup(sender, instance, *args, **kwargs): - """ - Deletes the file(s) associated with a model instance. The model - is not saved after deletion of the file(s) since this is meant - to be used with the pre_delete signal. - """ - for field_name, _ in instance.__dict__.iteritems(): - field = getattr(instance, field_name) - if (issubclass(field.__class__, FieldFile) and field.name): - # pass False so FileField does not save the model - field.delete(save=False) - - diff --git a/account/models.py b/account/models.py index 62276b8..4199941 100644 --- a/account/models.py +++ b/account/models.py @@ -13,7 +13,8 @@ from django.utils.translation import ugettext_lazy as _ from django.db.models.signals import pre_delete from registration.signals import user_registered, user_activated -from account.extra import ContentTypeRestrictedFileField, OverwriteStorage, file_cleanup +from account.extra import ContentTypeRestrictedFileField +from tools.storage import OverwriteStorage, file_cleanup import os diff --git a/archive/models.py b/archive/models.py index 47903e4..467caa4 100644 --- a/archive/models.py +++ b/archive/models.py @@ -1,14 +1,11 @@ # -*- coding: utf-8 -*- from django.db import models +from django.db.models.signals import pre_delete from django.contrib.auth.models import User -from django.contrib.contenttypes.models import ContentType -from django.contrib.contenttypes import generic from django.utils.translation import ugettext_lazy as _ -from django.db.models.signals import pre_delete - -from account.extra import OverwriteStorage, file_cleanup +from tools.storage import OverwriteStorage, file_cleanup class Archive(models.Model): diff --git a/notice/models.py b/notice/models.py index 92b34e5..3f33e4d 100644 --- a/notice/models.py +++ b/notice/models.py @@ -1,11 +1,14 @@ # -*- coding: utf-8 -*- from django.db import models +from django.db.models.signals import pre_delete from django.contrib.auth.models import User -from django.contrib.contenttypes.models import ContentType from django.contrib.contenttypes import generic +from django.contrib.contenttypes.models import ContentType from django.utils.translation import ugettext_lazy as _ +from tools.storage import OverwriteStorage, file_cleanup + class Notice(models.Model): """ @@ -52,7 +55,8 @@ class NoticeAttachment(models.Model): title = models.CharField(_("Title"), max_length=100) description = models.TextField(_("Description"), blank=True) attachment = models.FileField(upload_to='notice/attachments', - verbose_name=_("Attachment")) + verbose_name=_("Attachment"), + storage=OverwriteStorage) content_type = models.ForeignKey(ContentType) object_id = models.PositiveIntegerField() content_object = generic.GenericForeignKey("content_type", "object_id") @@ -62,3 +66,7 @@ class NoticeAttachment(models.Model): verbose_name_plural = _('notice attachments') +### connect to signal and sender +pre_delete.connect(file_cleanup, sender=NoticeAttachment) + + diff --git a/tools/storage.py b/tools/storage.py new file mode 100644 index 0000000..64f14d1 --- /dev/null +++ b/tools/storage.py @@ -0,0 +1,60 @@ +# -*- coding: utf-8 -*- +# +# custom storage class +# and storage related tools +# + +from django.conf import settings +from django.core.files.storage import FileSystemStorage +from django.db.models.fields.files import FieldFile + +import os + + +### OverwriteStorage ### +class OverwriteStorage(FileSystemStorage): + """ + overwrite original file before store the new one + """ + def get_available_name(self, name): + """ + Returns a filename that's free on the target storage system, + and available for new content to be written to. + Ref: http://djangosnippets.org/snippets/976/ + + This file storage solves overwrite on upload problem. Another + proposed solution was to override the save method on the model + like so (from https://code.djangoproject.com/ticket/11663): + + def save(self, *args, **kwargs): + try: + this = MyModelName.objects.get(id=self.id) + if this.MyImageFieldName != self.MyImageFieldName: + this.MyImageFieldName.delete() + except: pass + super(MyModelName, self).save(*args, **kwargs) + """ + # If the filename already exists, + # remove it as if it was a true file system + if self.exists(name): + filepath = os.path.join(settings.MEDIA_ROOT, name) + if os.path.isfile(filepath): + os.remove(filepath) + return name + + +### delete files associated with model FileField +# Pre-delete signal function for deleting files a model +# https://djangosnippets.org/snippets/2820/ +def file_cleanup(sender, instance, *args, **kwargs): + """ + Deletes the file(s) associated with a model instance. The model + is not saved after deletion of the file(s) since this is meant + to be used with the pre_delete signal. + """ + for field_name, _ in instance.__dict__.iteritems(): + field = getattr(instance, field_name) + if (issubclass(field.__class__, FieldFile) and field.name): + # pass False so FileField does not save the model + field.delete(save=False) + -- cgit v1.2.2