mirror of
https://github.com/Hopiu/django-imagekit.git
synced 2026-03-17 05:40:25 +00:00
Everything for dealing with files should be part of GeneratedImageCacheFile--not the generator. The fact that GeneratedImageCacheFile can get this information (storage, filename, etc.) is a convenience so that the user only has to define one class (the generator) to fully specify their functionality, but handling the cache file is not part of the core responsibility of the generator. This is also the reason for the renaming of `get_filename` and `storage` to `cache_file_name` and `cache_file_storage`: the generator is just as useful for those who want to generate persistent files. But the original attribute names didn't indicate that they were used only for cache files. The new ones do, and don't preclude the addition of other versions that would be used by another `File` subclass for specifying file names or storage classes.
88 lines
3.5 KiB
Python
88 lines
3.5 KiB
Python
from django.db import models
|
|
from .files import ProcessedImageFieldFile
|
|
from .utils import ImageSpecFileDescriptor
|
|
from ...specs import SpecHost
|
|
from ...specs.sourcegroups import ImageFieldSourceGroup
|
|
from ...registry import register
|
|
|
|
|
|
class SpecHostField(SpecHost):
|
|
def set_spec_id(self, cls, name):
|
|
# Generate a spec_id to register the spec with. The default spec id is
|
|
# "<app>:<model>_<field>"
|
|
if not getattr(self, 'spec_id', None):
|
|
spec_id = (u'%s:%s_%s' % (cls._meta.app_label,
|
|
cls._meta.object_name, name)).lower()
|
|
|
|
# Register the spec with the id. This allows specs to be overridden
|
|
# later, from outside of the model definition.
|
|
super(SpecHostField, self).set_spec_id(spec_id)
|
|
|
|
|
|
class ImageSpecField(SpecHostField):
|
|
"""
|
|
The heart and soul of the ImageKit library, ImageSpecField allows you to add
|
|
variants of uploaded images to your models.
|
|
|
|
"""
|
|
def __init__(self, processors=None, format=None, options=None,
|
|
source=None, cache_file_storage=None, autoconvert=None,
|
|
image_cache_backend=None, image_cache_strategy=None, spec=None,
|
|
id=None):
|
|
|
|
SpecHost.__init__(self, processors=processors, format=format,
|
|
options=options, cache_file_storage=cache_file_storage,
|
|
autoconvert=autoconvert,
|
|
image_cache_backend=image_cache_backend,
|
|
image_cache_strategy=image_cache_strategy, spec=spec,
|
|
spec_id=id)
|
|
|
|
# TODO: Allow callable for source. See https://github.com/jdriscoll/django-imagekit/issues/158#issuecomment-10921664
|
|
self.source = source
|
|
|
|
def contribute_to_class(self, cls, name):
|
|
setattr(cls, name, ImageSpecFileDescriptor(self, name))
|
|
self.set_spec_id(cls, name)
|
|
|
|
# Add the model and field as a source for this spec id
|
|
register.sources(self.spec_id,
|
|
[ImageFieldSourceGroup(cls, self.source)])
|
|
|
|
|
|
class ProcessedImageField(models.ImageField, SpecHostField):
|
|
"""
|
|
ProcessedImageField is an ImageField that runs processors on the uploaded
|
|
image *before* saving it to storage. This is in contrast to specs, which
|
|
maintain the original. Useful for coercing fileformats or keeping images
|
|
within a reasonable size.
|
|
|
|
"""
|
|
attr_class = ProcessedImageFieldFile
|
|
|
|
def __init__(self, processors=None, format=None, options=None,
|
|
verbose_name=None, name=None, width_field=None, height_field=None,
|
|
autoconvert=True, spec=None, spec_id=None, **kwargs):
|
|
"""
|
|
The ProcessedImageField constructor accepts all of the arguments that
|
|
the :class:`django.db.models.ImageField` constructor accepts, as well
|
|
as the ``processors``, ``format``, and ``options`` arguments of
|
|
:class:`imagekit.models.ImageSpecField`.
|
|
|
|
"""
|
|
SpecHost.__init__(self, processors=processors, format=format,
|
|
options=options, autoconvert=autoconvert, spec=spec,
|
|
spec_id=spec_id)
|
|
models.ImageField.__init__(self, verbose_name, name, width_field,
|
|
height_field, **kwargs)
|
|
|
|
def contribute_to_class(self, cls, name):
|
|
self.set_spec_id(cls, name)
|
|
return super(ProcessedImageField, self).contribute_to_class(cls, name)
|
|
|
|
|
|
try:
|
|
from south.modelsinspector import add_introspection_rules
|
|
except ImportError:
|
|
pass
|
|
else:
|
|
add_introspection_rules([], [r'^imagekit\.models\.fields\.ProcessedImageField$'])
|