References¶
Preview¶
Any field which use the widget ClearableFileInputButton
would have a specific
look when editing.
Obviously, there won’t be any preview or clear checkbox when field is empty. In this case only the upload button will be showed.
Widgets¶
Widgets are just about HTML and layout, nothing more. There are different widgets so use
the one which fullfil your needs but to know ClearableFileInputButton
is the most
featured one.
The base versions does not include widget stylesheet and Javascript assets so you can include them yourself. This is helpful in some specific situations when you want to make layout integration yourself but commonly you will prefer the non-base widgets.
- class smart_media.widgets.FileInputButtonBase(attrs=None)[source]¶
A simple FileInput override to use a custom template.
The custom template is located at
smart_image/fileinputbutton_basic.html
, you may override it in your project if needed, but mind it is global to all SmartMedia widgets.Default behavior if no
class
attribute is given is to apply the CSS classnamefileinputbutton__input
to the input.Note
When your input file enable the
multiple
attribute to accept more than one file, label input will be rendered to a default string like “4 files” which is not translatable (this is done in the Javascript source).If you want a translatable string just pass it to widget instance attribute
data-multiple-caption
like:FileInputButton(attrs={ "data-multiple-caption": gettext_lazy("{count} files selected") })
Pattern
{count}
will be replaced with the number of selected files.
- class smart_media.widgets.ClearableFileInputButtonBase(attrs=None)[source]¶
Alike
FileInputButtonBase
but to extend with the additional clear checkbox.This won’t support the “multiple” input file feature.
- class smart_media.widgets.FileInputButton(attrs=None)[source]¶
FileInputButtonBase
version which includes the required assets to customize its layout and turn the file input as a button.This widget will define a stylesheet and a Javascript asset to load as form medias, this automatically done from admin but you will probably have to load them on your own in a custom form.
Stylesheet is located at
smart_image/css/fileinputbutton.css
(relative to static directory);Javascript is located at
smart_image/js/fileinputbutton.js
(relative to static directory);
You can retrieve these assets sources in repository, note than the CSS is built from a Sass source you may copy into your project Sass sources.
Form Fields¶
Form fields implement widgets for FileField
and ImageField
but they are less
easy to use with a model form.
- class smart_media.fields.SmartMediaField(*, max_length=None, allow_empty_file=False, **kwargs)[source]¶
A FileField which define the widget
ClearableFileInputButton
and default validatorFileExtensionValidator
for allowed extensions (as defined from settingSMARTIMAGE_ALLOWED_IMAGE_EXTENSIONS
).Note
Validation is pretty basic since it works on file extension, no malicious Bitmap or SVG image files would be detected here. If it is a concern, you will have to develop or use an additional validator.
- widget¶
alias of
ClearableFileInputButton
- class smart_media.fields.SmartImageField(*, max_length=None, allow_empty_file=False, **kwargs)[source]¶
An ImageField which define the widget
ClearableFileInputButton
, the default validator is still the one from ImageField and so the field won’t allow for SVG file.- widget¶
alias of
ClearableFileInputButton
Model Fields¶
- class smart_media.modelfields.SmartMediaField(verbose_name=None, name=None, upload_to='', storage=None, **kwargs)[source]¶
A model file field with every “smart” features.
Set the
SmartMediaFileExtensionValidator
validator;Use the form field
SmartMediaField
to get the proper “smart” clearable file widget;Generate filename as an unique UUID with
uploadto_unique
function;
Example
Usage is identical to a
models.FileField
:cover = SmartMediaField( "cover", max_length=255, null=True, blank=True, default=None, upload_to="sample/cover/%y/%m", )
Note
If attribute
upload_to
value is a callable then the UUID filename behavior is disabled.Note
Sadly this just won’t work on its own in Django admin which makes some internal resolutions between model fields and widgets. So you will need to define a rule to get the right widget for this field, see
smart_media.admin.SmartModelAdmin
.Warning
Django won’t be able to detect change on settings. So you will have to create a custom data migration on your own if you want to clean files with previously allowed extensions but removed from setting.
Model signals¶
These signals are not mandatory but are very helpful to automatically clean your media directory from stall files.
They are on your own to implement in your models still it is very easy to do and do not require any migrations.
Warning
Purge signals can be harmful on very specific case if you blindly implement them without thinking about your application behaviors.
For example, it is known that plugins from DjangoCMS are cloned on each save, for
this reason the signal auto_purge_files_on_delete
must not be connected to
a DjangoCMS plugin model because it deletes cloned object files without copying them
first for new clone. It results on plugin objects keeping references to files that
have been removed by the “on delete” purge signal (since cloning imply to copy then
delete).
You need to think if your models are doing post processing saves on object.
- smart_media.signals.auto_purge_files_on_delete(fieldnames)[source]¶
Return a callable to set as a signal receiver to purge related files from deleted object.
When connected to your model, just before an object is deleted the signal check defined fields for their files and remove them from your Filesystem so you won’t keep files from object that do not exists anymore.
This is to be used with signal
django.db.models.signals.post_delete
and since this work with shallow function you will need to setweak=False
on signal methodconnect
.Example
Commonly you connect signal in your models file and define a list of fields to watch for purge:
from django.db import models from django.db.models.signals import post_delete from smart_media.signals import auto_purge_files_on_delete class MyModel(models.Model): cover = models.FileField(...) post_delete.connect( auto_purge_files_on_delete(["cover"]), dispatch_uid="mymodels_files_on_delete", sender=MyModel, weak=False, )
Remember to set an unique key name to argument
dispatch_uid
.- Parameters:
fieldnames (list) – List of model field names to seek for file to remove. If a given field name does not exists for given model instance an exception is raised. It is important to keep this list up to date with your model.
- Returns
callable: A callable function with expected signature from signal emitter.
- smart_media.signals.auto_purge_files_on_change(fieldnames)[source]¶
Return a callable to set as a signal receiver to purge old related files for a modified object with new uploaded files.
When connected to your model, just before an existing object is saved the signal check defined fields for their current files, if a current file is different than the one from the changes, it is removed from your Filesystem so you won’t keep files that have been deleted or changed.
It is safe if old file does not exists anymore.
This is to be used with signal
django.db.models.signals.pre_save
and since this work with shallow function you will need to setweak=False
on signal methodconnect
.This receiver perform an additional get queryset on object to get its previous value just before current save.
Example
Commonly you connect signal in your models file and define a list of fields to watch for purge:
from django.db import models from django.db.models.signals import pre_save from smart_media.signals import auto_purge_files_on_change class MyModel(models.Model): cover = models.FileField(...) pre_save.connect( auto_purge_files_on_change(["cover"]), dispatch_uid="mymodels_files_on_change", sender=MyModel, weak=False, )
Remember to set an unique key name to argument
dispatch_uid
.- Parameters:
fieldnames (list) – List of model field names to seek for file to remove. If a given field name does not exists for given model instance an exception is raised. It is important to keep this list up to date with your model.
- Returns
callable: A callable function with expected signature from signal emitter.
Django admin¶
- class smart_media.admin.SmartAdminMixin[source]¶
A class to mix with a Django admin class to the use right widget definition for model field
modelfields.SmartMediaField
.Note
This is required because ModelAdmin translate model fields to widgets using a list of harcoded relations between fields and widgets.
It results in field definitions from
SmartMediaField.formfield
to be ignored andSmartMediaField
using admin widgetAdminFileWidget
instead of expectedClearableFileInputButton
.This mixin will be safe to use with specific model admins that does not allows to inherit from
SmartModelAdmin
.Example
Your model admin just have to inherit from this class in addition to the model admin class:
from django.contrib import admin from smart_media.admin import SmartAdminMixin from myapp.models import MyModel @admin.register(MyModel) class MyModelAdmin(SmartAdminMixin, admin.ModelAdmin): ...
If you can’t use it, just copy the source of
SmartAdminMixin.formfield_overrides
(see source) into your own model admin.
- class smart_media.admin.SmartModelAdmin(model, admin_site)[source]¶
A model admin class to include
SmartAdminMixin
.It is only required with model forms in Django admin. If your model admin already inherit from a specific admin class, you will prefer to use the
SmartAdminMixin
.Example
Your model admin just have to inherit from this class:
from django.contrib import admin from smart_media.admin import SmartModelAdmin from myapp.models import MyModel @admin.register(MyModel) class MyModelAdmin(SmartModelAdmin): ...
Mixin¶
A mixin object exists to get the right image format name. It is used internally in template tag but you can also inherit it from a model if you need this format name somewhere in your code.
- class smart_media.mixins.SmartFormatMixin[source]¶
A mixin to inherit from a model so it will have a helper method to manage image formats.
Example
You just have to inherit this class then define a method dedicated to your field:
from django.db import models from smart_media.mixins import SmartFormatMixin from smart_media.modelfields import SmartMediaField class MyModel(SmartFormatMixin, models.Model): media = SmartMediaField( "media", max_length=255, null=True, blank=True, default=None, upload_to="sample/media/%y/%m", ) def get_media_format(self): return self.media_format(self.media)
- media_format(mediafile)[source]¶
Common method to perform a naive check about image format using file extension.
Retrieved format will come from setting
SMART_FORMAT_AVAILABLE_FORMATS
.Obviously since it use the file extension, found format is not to be 100% trusted. You may think about validate your files strictly if strong security is a matter for you and file upload is open to untrusted user.
- Parameters:
mediafile (object) – Either a FileField, ImageField or any other object which implement a
name
attribute which return the filename.- Returns:
Format name if filename extension match to any available format extension from available formats else it returns
None
.- Return type:
string
SVG¶
To ensure compatibility for both Bitmap and SVG format, we aim to ensure template tag return can be used in the same way with thumbnail library.
So for a SVG file we return a SvgFile which implement basic attributes and methods alike Sorl ImageFile.
Note
Commonly you won’t have to deal with it directly so don’t bother anymore if you are not trying to implement something very specific.
- class smart_media.thumbnailing.SvgFile(fileobject, storage=None)[source]¶
Object to mimic Sorl object
thumbnail.images.ImageFile
and implement some of its attributes and methods.All other method about image size are not supported.
- name¶
File name, aka its relative path from its storage.
- Type:
string
- url¶
Full media file url from its storage.
- Type:
string
- Parameters:
fileobject (django.core.files.File) – A valid Django file object.
- Keyword Arguments:
storage (django.core.files.storage.FileSystemStorage) – Storage related to the file. If not given, the default Django storage backend is used.
Exceptions¶
Application parts may raise specific exceptions, it may be helpful to recognize them.
- exception smart_media.exceptions.SmartImageBaseException[source]¶
Base for every SmartFormat template tag exceptions.
- exception smart_media.exceptions.InvalidFormatError[source]¶
Exception to be raised from smart_format template tag when given format is not invalid.
Optional contributions¶
There you could find some useful optional contributions for some feature or packages.
- class smart_media.contrib.django_configuration.SmartMediaDefaultSettings[source]¶
Default “Django smart media” settings class to use with a “django-configuration” class.
Example
You could use it like so:
from configurations import Configuration from smart_media.contrib.django_configuration import ( SmartMediaDefaultSettings, ) class Dev(SmartMediaDefaultSettings, Configuration): DEBUG = True SMARTIMAGE_FILESIZE_LIMIT = 142
This will override only the setting
SMARTIMAGE_FILESIZE_LIMIT
, all other SmartMedia settings will have the default values fromsmart_media.settings
.