From c8ce68e7b847a69dbfd2e2ec251b3668c7fbd112 Mon Sep 17 00:00:00 2001 From: Ross Poulton Date: Tue, 30 Dec 2008 00:41:47 +0000 Subject: [PATCH] Fix issue #37 - file uploading was not working as it should. File uploading now works correctly from both the staff interface and from emails. --- management/commands/get_email.py | 2 +- models.py | 41 +++++++++++++------------------- templates/helpdesk/ticket.html | 2 +- views/staff.py | 9 +++---- 4 files changed, 23 insertions(+), 31 deletions(-) diff --git a/management/commands/get_email.py b/management/commands/get_email.py index ddd72ce4..71aa1fdf 100644 --- a/management/commands/get_email.py +++ b/management/commands/get_email.py @@ -276,7 +276,7 @@ def ticket_from_message(message, queue): mime_type=file['type'], size=len(file['content']), ) - a.file.save(file['filename'], ContentFile(file['content'])) + a.file.save(file['filename'], ContentFile(file['content']), save=False) a.save() print " - %s" % file['filename'] diff --git a/models.py b/models.py index 0a461430..8bb804fd 100644 --- a/models.py +++ b/models.py @@ -543,31 +543,22 @@ class TicketChange(models.Model): return str -class DynamicFileField(models.FileField): +def attachment_path(instance, filename): """ - Allows model instance to specify upload_to dynamically. - - Model class should have a method like: - - def get_upload_to(self, attname): - return 'path/to/%d' % self.parent.id - - Based on: http://scottbarnham.com/blog/2007/07/31/uploading-images-to-a-dynamic-path-with-django/ + Provide a file path that will help prevent files being overwritten, by + putting attachments in a folder off attachments for ticket/followup_id/. """ - - def contribute_to_class(self, cls, name): - """Hook up events so we can access the instance.""" - super(DynamicFileField, self).contribute_to_class(cls, name) - models.signals.post_init.connect(self._post_init, sender=cls) - - def _post_init(self, instance=None, **kwargs): - """Get dynamic upload_to value from the model instance.""" - if hasattr(instance, 'get_upload_to'): - self.upload_to = instance.get_upload_to(self.attname) - - def db_type(self): - """Required by Django for ORM.""" - return 'varchar(100)' + import os + from django.conf import settings + os.umask(0) + path = 'helpdesk/attachments/%s/%s' % (instance.followup.ticket.ticket_for_url, instance.followup.id ) + try: + os.makedirs(os.path.join(settings.MEDIA_ROOT, path), 0777) + except OSError,e: + if e[0] != 17: + # 17 = 'File exists' + raise e + return os.path.join(path, filename) class Attachment(models.Model): @@ -578,9 +569,9 @@ class Attachment(models.Model): followup = models.ForeignKey(FollowUp) - file = DynamicFileField( + file = models.FileField( _('File'), - upload_to='helpdesk/attachments', + upload_to=attachment_path, ) filename = models.CharField( diff --git a/templates/helpdesk/ticket.html b/templates/helpdesk/ticket.html index 08d938ba..d38dfc93 100644 --- a/templates/helpdesk/ticket.html +++ b/templates/helpdesk/ticket.html @@ -97,7 +97,7 @@ {% if forloop.last %}{% endif %} {% endfor %} {% for attachment in followup.attachment_set.all %}{% if forloop.first %}
{% endif %} {% endfor %} diff --git a/views/staff.py b/views/staff.py index 760fdd67..6a62dd3c 100644 --- a/views/staff.py +++ b/views/staff.py @@ -267,15 +267,16 @@ def update_ticket(request, ticket_id): ) if request.FILES: + import mimetypes for file in request.FILES.getlist('attachment'): - filename = file['filename'].replace(' ', '_') + filename = file.name.replace(' ', '_') a = Attachment( followup=f, filename=filename, - mime_type=file['content-type'], - size=len(file['content']), + mime_type=mimetypes.guess_type(filename)[0] or 'application/octet-stream', + size=file.size, ) - a.file.save(file['filename'], ContentFile(file['content'])) + a.file.save(file.name, file, save=False) a.save() ticket.save()