diff --git a/browse_and_upload_field/fields.py b/browse_and_upload_field/fields.py index 07e93e1..728e2aa 100644 --- a/browse_and_upload_field/fields.py +++ b/browse_and_upload_field/fields.py @@ -3,9 +3,11 @@ # PYTHON IMPORTS import os +from django.utils.six import string_types + # DJANGO IMPORTS from django.conf import settings -from django.core import urlresolvers +from django.urls import reverse from django.core.files.move import file_move_safe from django.core.files.storage import get_storage_class from django.db import models @@ -17,10 +19,11 @@ from django.utils.six import with_metaclass from django.utils.translation import ugettext_lazy as _ from django.contrib.admin.templatetags.admin_static import static +from django.contrib.admin.options import FORMFIELD_FOR_DBFIELD_DEFAULTS # FILEBROWSER IMPORTS -from filebrowser.settings import UPLOAD_TEMPDIR, ADMIN_THUMBNAIL, EXTENSIONS from filebrowser.base import FileObject +from filebrowser.settings import ADMIN_THUMBNAIL, EXTENSIONS, UPLOAD_TEMPDIR from filebrowser.sites import site @@ -43,7 +46,8 @@ class Media: def __init__(self, attrs=None): super(FileBrowseAndUploadWidget, self).__init__(attrs) - self.site = attrs.get('filebrowser_site', '') + self.site = attrs.get('filebrowser_site', None) + #self.site = attrs.get('site', '') self.directory = attrs.get('directory', '') self.extensions = attrs.get('extensions', '') self.format = attrs.get('format', '') @@ -55,8 +59,8 @@ def __init__(self, attrs=None): self.attrs = {} super(FileBrowseAndUploadWidget, self).__init__(attrs) - def render(self, name, value, attrs=None): - url = urlresolvers.reverse(self.site.name + ":fb_browse") + def render(self, name, value, attrs=None, renderer=None): + url = reverse(self.site.name + ":fb_browse") if value is None: value = "" if value != "" and not isinstance(value, FileObject): @@ -80,7 +84,13 @@ def render(self, name, value, attrs=None): pass return render_to_string("filebrowser/custom_browse_and_upload_field.html", locals()) - + def build_attrs(self, extra_attrs=None, **kwargs): + "Helper function for building an attribute dictionary." + attrs = dict(self.attrs, **kwargs) + if extra_attrs: + attrs.update(extra_attrs) + return attrs + class FileBrowseAndUploadFormField(forms.CharField): default_error_messages = { @@ -99,7 +109,7 @@ def __init__(self, max_length=None, min_length=None, site=None, directory=None, def clean(self, value): value = super(FileBrowseAndUploadFormField, self).clean(value) - if value == '': + if not value: return value file_extension = os.path.splitext(value)[1].lower() if self.extensions and file_extension not in self.extensions: @@ -107,7 +117,7 @@ def clean(self, value): return value -class FileBrowseAndUploadField(with_metaclass(models.SubfieldBase, CharField)): +class FileBrowseAndUploadField(CharField): description = "FileBrowseAndUploadField" @@ -126,6 +136,9 @@ def to_python(self, value): return value return FileObject(value, site=self.site) + def from_db_value(self, value, expression, connection, context): + return self.to_python(value) + def get_db_prep_value(self, value, connection, prepared=False): if not value: return value @@ -135,18 +148,20 @@ def get_db_prep_value(self, value, connection, prepared=False): return value def get_prep_value(self, value): - if not value: + if not value or isinstance(value, string_types): return value return value.path def value_to_string(self, obj): - value = self._get_val_from_obj(obj) - if not value: + value = self.value_from_object(obj) + if not value or isinstance(value, string_types): return value return value.path def formfield(self, **kwargs): + widget_class = kwargs.get('widget', FileBrowseAndUploadWidget) attrs = {} + attrs["site"] = self.site attrs["filebrowser_site"] = self.site attrs["directory"] = self.directory attrs["extensions"] = self.extensions @@ -155,7 +170,8 @@ def formfield(self, **kwargs): attrs["temp_upload_dir"] = self.temp_upload_dir defaults = { 'form_class': FileBrowseAndUploadFormField, - 'widget': FileBrowseAndUploadWidget(attrs=attrs), + 'widget': widget_class(attrs=attrs), + 'site': self.site, 'filebrowser_site': self.site, 'directory': self.directory, 'extensions': self.extensions, @@ -166,20 +182,20 @@ def formfield(self, **kwargs): return super(FileBrowseAndUploadField, self).formfield(**defaults) def upload_callback(self, sender, instance, **kwargs): - opts = instance._meta - field = getattr(instance, self.name) + value = getattr(instance, self.name) + if not value or isinstance(value, string_types): + return value - if field: - - filename = os.path.basename(smart_text(field.filename)) + if value and getattr(value, 'filename', None): + filename = os.path.basename(smart_text(value.filename)) upload_to = opts.get_field(self.name).upload_to filebrowser_directory = self.site.directory if getattr(upload_to, '__call__', None): upload_to = os.path.split(upload_to(instance, filename))[0] - if self.temp_upload_dir in field.path: + if self.temp_upload_dir in value.path: new_file = get_storage_class()().get_available_name( os.path.join( settings.MEDIA_ROOT, @@ -191,24 +207,28 @@ def upload_callback(self, sender, instance, **kwargs): new_path = os.path.split(new_file)[0] if not os.path.isdir(new_path): os.makedirs(new_path) - os.chmod(new_path, 0775) - file_move_safe(os.path.join(settings.MEDIA_ROOT, field.path), new_file, allow_overwrite=False) - os.chmod(new_file, 0775) + os.chmod(new_path, 0o775) + file_move_safe(os.path.join(settings.MEDIA_ROOT, value.path), new_file, allow_overwrite=False) + os.chmod(new_file, 0o775) setattr(instance, self.name, new_file.replace(settings.MEDIA_ROOT + "/", "")) instance.save() # Now generate all versions if this is an image if self.format.title() == 'Image': for v in settings.FILEBROWSER_VERSIONS: + instance.refresh_from_db() # Getattr again as the property has been changed version = getattr(instance, self.name).version_generate(v) - os.chmod(os.path.join(settings.MEDIA_ROOT, version.path), 0775) + os.chmod(os.path.join(settings.MEDIA_ROOT, version.path), 0o775) def contribute_to_class(self, cls, name): models.signals.post_save.connect(self.upload_callback, sender=cls) super(FileBrowseAndUploadField, self).contribute_to_class(cls, name) +FORMFIELD_FOR_DBFIELD_DEFAULTS[FileBrowseAndUploadField] = {'widget': FileBrowseAndUploadWidget} + + if 'south' in settings.INSTALLED_APPS: from south.modelsinspector import add_introspection_rules add_introspection_rules([], ["^filebrowser\.fields\.FileBrowseAndUploadField"]) diff --git a/browse_and_upload_field/site.py b/browse_and_upload_field/site.py index 69b11f0..0081c93 100644 --- a/browse_and_upload_field/site.py +++ b/browse_and_upload_field/site.py @@ -2,7 +2,7 @@ import os import re -from django.core.urlresolvers import reverse +from django.urls import reverse from django.http import HttpResponse, HttpResponseBadRequest from django.utils.encoding import smart_text diff --git a/browse_and_upload_field/templates/filebrowser/custom_browse_and_upload_field.html b/browse_and_upload_field/templates/filebrowser/custom_browse_and_upload_field.html index 55aeb79..fd81bb1 100644 --- a/browse_and_upload_field/templates/filebrowser/custom_browse_and_upload_field.html +++ b/browse_and_upload_field/templates/filebrowser/custom_browse_and_upload_field.html @@ -10,7 +10,7 @@ {% if value.filetype == "Image" %} - {% version_object value.path final_attrs.ADMIN_THUMBNAIL as thumbnail_version %} + {% version value.path final_attrs.ADMIN_THUMBNAIL as thumbnail_version %} {% if thumbnail_version %}