diff options
| author | Yuval Adam <yuval@segmanta.com> | 2014-03-20 17:49:16 +0200 |
|---|---|---|
| committer | Yuval Adam <yuval@segmanta.com> | 2014-03-20 17:49:16 +0200 |
| commit | 75f93a3f7854a7383febd047391e2bfd4caceee0 (patch) | |
| tree | d5e634ef292c6b84acacc3982dbcaa0d300a346e /examples | |
Diffstat (limited to 'examples')
| -rw-r--r-- | examples/cloudfiles_project/__init__.py | 0 | ||||
| -rwxr-xr-x | examples/cloudfiles_project/manage.py | 11 | ||||
| -rw-r--r-- | examples/cloudfiles_project/photos/__init__.py | 0 | ||||
| -rw-r--r-- | examples/cloudfiles_project/photos/admin.py | 4 | ||||
| -rw-r--r-- | examples/cloudfiles_project/photos/models.py | 9 | ||||
| -rw-r--r-- | examples/cloudfiles_project/settings.py | 83 | ||||
| -rw-r--r-- | examples/cloudfiles_project/templates/base.html | 14 | ||||
| -rw-r--r-- | examples/cloudfiles_project/templates/photos/photo_list.html | 14 | ||||
| -rw-r--r-- | examples/cloudfiles_project/urls.py | 21 | ||||
| -rw-r--r-- | examples/libcloud_project/manage.py | 14 | ||||
| -rw-r--r-- | examples/libcloud_project/settings.py | 160 | ||||
| -rw-r--r-- | examples/libcloud_project/test_storage.py | 14 | ||||
| -rw-r--r-- | examples/libcloud_project/urls.py | 17 | ||||
| -rw-r--r-- | examples/s3project/__init__.py | 0 | ||||
| -rw-r--r-- | examples/s3project/manage.py | 15 | ||||
| -rw-r--r-- | examples/s3project/models.py | 25 | ||||
| -rw-r--r-- | examples/s3project/settings.py | 52 | ||||
| -rw-r--r-- | examples/s3project/tests.py | 200 |
18 files changed, 653 insertions, 0 deletions
diff --git a/examples/cloudfiles_project/__init__.py b/examples/cloudfiles_project/__init__.py new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/examples/cloudfiles_project/__init__.py diff --git a/examples/cloudfiles_project/manage.py b/examples/cloudfiles_project/manage.py new file mode 100755 index 0000000..5e78ea9 --- /dev/null +++ b/examples/cloudfiles_project/manage.py @@ -0,0 +1,11 @@ +#!/usr/bin/env python +from django.core.management import execute_manager +try: + import settings # Assumed to be in the same directory. +except ImportError: + import sys + sys.stderr.write("Error: Can't find the file 'settings.py' in the directory containing %r. It appears you've customized things.\nYou'll have to run django-admin.py, passing it your settings module.\n(If the file settings.py does indeed exist, it's causing an ImportError somehow.)\n" % __file__) + sys.exit(1) + +if __name__ == "__main__": + execute_manager(settings) diff --git a/examples/cloudfiles_project/photos/__init__.py b/examples/cloudfiles_project/photos/__init__.py new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/examples/cloudfiles_project/photos/__init__.py diff --git a/examples/cloudfiles_project/photos/admin.py b/examples/cloudfiles_project/photos/admin.py new file mode 100644 index 0000000..74141c5 --- /dev/null +++ b/examples/cloudfiles_project/photos/admin.py @@ -0,0 +1,4 @@ +from django.contrib import admin +from cloudfiles_project.photos.models import Photo + +admin.site.register(Photo)
\ No newline at end of file diff --git a/examples/cloudfiles_project/photos/models.py b/examples/cloudfiles_project/photos/models.py new file mode 100644 index 0000000..0770a3d --- /dev/null +++ b/examples/cloudfiles_project/photos/models.py @@ -0,0 +1,9 @@ +from django.db import models +from backends.mosso import cloudfiles_upload_to + +class Photo(models.Model): + title = models.CharField(max_length=50) + image = models.ImageField(upload_to=cloudfiles_upload_to) + + def __unicode__(self): + return self.title
\ No newline at end of file diff --git a/examples/cloudfiles_project/settings.py b/examples/cloudfiles_project/settings.py new file mode 100644 index 0000000..6c18122 --- /dev/null +++ b/examples/cloudfiles_project/settings.py @@ -0,0 +1,83 @@ +DEBUG = True +TEMPLATE_DEBUG = DEBUG + +ADMINS = ( + # ('Your Name', 'your_email@domain.com'), +) + +MANAGERS = ADMINS + +CLOUDFILES_USERNAME = 'yourusername' +CLOUDFILES_API_KEY = 'yourapikey' +CLOUDFILES_CONTAINER = 'test-container' +CLOUDFILES_TTL = 600 +DEFAULT_FILE_STORAGE = 'backends.mosso.CloudFilesStorage' + +DATABASE_ENGINE = 'sqlite3' # 'postgresql_psycopg2', 'postgresql', 'mysql', 'sqlite3' or 'oracle'. +DATABASE_NAME = 'local.db' # Or path to database file if using sqlite3. +DATABASE_USER = '' # Not used with sqlite3. +DATABASE_PASSWORD = '' # Not used with sqlite3. +DATABASE_HOST = '' # Set to empty string for localhost. Not used with sqlite3. +DATABASE_PORT = '' # Set to empty string for default. Not used with sqlite3. + +# Local time zone for this installation. Choices can be found here: +# http://en.wikipedia.org/wiki/List_of_tz_zones_by_name +# although not all choices may be available on all operating systems. +# If running in a Windows environment this must be set to the same as your +# system time zone. +TIME_ZONE = 'America/New_York' + +# Language code for this installation. All choices can be found here: +# http://www.i18nguy.com/unicode/language-identifiers.html +LANGUAGE_CODE = 'en-us' + +SITE_ID = 1 + +# If you set this to False, Django will make some optimizations so as not +# to load the internationalization machinery. +USE_I18N = True + +# Absolute path to the directory that holds media. +# Example: "/home/media/media.lawrence.com/" +MEDIA_ROOT = '' + +# URL that handles the media served from MEDIA_ROOT. Make sure to use a +# trailing slash if there is a path component (optional in other cases). +# Examples: "http://media.lawrence.com", "http://example.com/media/" +MEDIA_URL = '/media/' + +# URL prefix for admin media -- CSS, JavaScript and images. Make sure to use a +# trailing slash. +# Examples: "http://foo.com/media/", "/media/". +ADMIN_MEDIA_PREFIX = '/media/admin/' + +# Make this unique, and don't share it with anybody. +SECRET_KEY = '5-7e5&o20#&@&h8t)7%n4a@)y7s3(jnv)qdd_azqzmo826d_u@' + +# List of callables that know how to import templates from various sources. +TEMPLATE_LOADERS = ( + 'django.template.loaders.filesystem.load_template_source', + 'django.template.loaders.app_directories.load_template_source', +# 'django.template.loaders.eggs.load_template_source', +) + +MIDDLEWARE_CLASSES = ( + 'django.middleware.common.CommonMiddleware', + 'django.contrib.sessions.middleware.SessionMiddleware', + 'django.contrib.auth.middleware.AuthenticationMiddleware', +) + +ROOT_URLCONF = 'cloudfiles_project.urls' + +TEMPLATE_DIRS = ( + 'templates', +) + +INSTALLED_APPS = ( + 'django.contrib.auth', + 'django.contrib.contenttypes', + 'django.contrib.sessions', + 'django.contrib.sites', + 'django.contrib.admin', + 'cloudfiles_project.photos', +) diff --git a/examples/cloudfiles_project/templates/base.html b/examples/cloudfiles_project/templates/base.html new file mode 100644 index 0000000..8a8a137 --- /dev/null +++ b/examples/cloudfiles_project/templates/base.html @@ -0,0 +1,14 @@ +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" + "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> + +<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en"> +<head> + <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/> + <title>django-cumulus example project</title> +</head> + +<body> +{% block content %}{% endblock %} + +</body> +</html> diff --git a/examples/cloudfiles_project/templates/photos/photo_list.html b/examples/cloudfiles_project/templates/photos/photo_list.html new file mode 100644 index 0000000..81a49a5 --- /dev/null +++ b/examples/cloudfiles_project/templates/photos/photo_list.html @@ -0,0 +1,14 @@ +{% extends "base.html" %} + +{% block content %} +<h1>Photos in database</h1> +{% if object_list %} +<ul>{% spaceless %} + {% for object in object_list %} + <li>{{ object.image.url }}</li> + {% endfor %} +{% endspaceless %}</ul> +{% else %} +<p>No photos exist.</p> +{% endif %} +{% endblock %} diff --git a/examples/cloudfiles_project/urls.py b/examples/cloudfiles_project/urls.py new file mode 100644 index 0000000..b566697 --- /dev/null +++ b/examples/cloudfiles_project/urls.py @@ -0,0 +1,21 @@ +from django.conf.urls.defaults import * +from django.conf import settings +from photos.models import Photo + +photo_dict = { + 'queryset': Photo.objects.all() +} + +from django.contrib import admin +admin.autodiscover() + +urlpatterns = patterns('', + (r'^admin/doc/', include('django.contrib.admindocs.urls')), + (r'^admin/(.*)', admin.site.root), + (r'^photos/$', 'django.views.generic.list_detail.object_list', photo_dict), +) + +if settings.DEBUG: + urlpatterns += patterns('', + (r'^media/(?P<path>.*)$', 'django.views.static.serve', {'document_root': settings.MEDIA_ROOT}), + )
\ No newline at end of file diff --git a/examples/libcloud_project/manage.py b/examples/libcloud_project/manage.py new file mode 100644 index 0000000..3e4eedc --- /dev/null +++ b/examples/libcloud_project/manage.py @@ -0,0 +1,14 @@ +#!/usr/bin/env python +from django.core.management import execute_manager +import imp +try: + imp.find_module('settings') # Assumed to be in the same directory. +except ImportError: + import sys + sys.stderr.write("Error: Can't find the file 'settings.py' in the directory containing %r. It appears you've customized things.\nYou'll have to run django-admin.py, passing it your settings module.\n" % __file__) + sys.exit(1) + +import settings + +if __name__ == "__main__": + execute_manager(settings) diff --git a/examples/libcloud_project/settings.py b/examples/libcloud_project/settings.py new file mode 100644 index 0000000..3d7bac9 --- /dev/null +++ b/examples/libcloud_project/settings.py @@ -0,0 +1,160 @@ +# Django settings for libcloud_project project. + +DEBUG = True +TEMPLATE_DEBUG = DEBUG + +ADMINS = ( + # ('Your Name', 'your_email@example.com'), +) + +MANAGERS = ADMINS + +DATABASES = { + 'default': { + 'ENGINE': 'django.db.backends.sqlite3', # Add 'postgresql_psycopg2', 'postgresql', 'mysql', 'sqlite3' or 'oracle'. + 'NAME': 'libcloud_project.sqllite', # Or path to database file if using sqlite3. + 'USER': '', # Not used with sqlite3. + 'PASSWORD': '', # Not used with sqlite3. + 'HOST': '', # Set to empty string for localhost. Not used with sqlite3. + 'PORT': '', # Set to empty string for default. Not used with sqlite3. + } +} + +# Local time zone for this installation. Choices can be found here: +# http://en.wikipedia.org/wiki/List_of_tz_zones_by_name +# although not all choices may be available on all operating systems. +# On Unix systems, a value of None will cause Django to use the same +# timezone as the operating system. +# If running in a Windows environment this must be set to the same as your +# system time zone. +TIME_ZONE = 'America/Chicago' + +# Language code for this installation. All choices can be found here: +# http://www.i18nguy.com/unicode/language-identifiers.html +LANGUAGE_CODE = 'en-us' + +SITE_ID = 1 + +# If you set this to False, Django will make some optimizations so as not +# to load the internationalization machinery. +USE_I18N = True + +# If you set this to False, Django will not format dates, numbers and +# calendars according to the current locale +USE_L10N = True + +# Absolute filesystem path to the directory that will hold user-uploaded files. +# Example: "/home/media/media.lawrence.com/media/" +MEDIA_ROOT = '' + +# URL that handles the media served from MEDIA_ROOT. Make sure to use a +# trailing slash. +# Examples: "http://media.lawrence.com/media/", "http://example.com/media/" +MEDIA_URL = '' + +# Absolute path to the directory static files should be collected to. +# Don't put anything in this directory yourself; store your static files +# in apps' "static/" subdirectories and in STATICFILES_DIRS. +# Example: "/home/media/media.lawrence.com/static/" +STATIC_ROOT = '' + +# URL prefix for static files. +# Example: "http://media.lawrence.com/static/" +STATIC_URL = '/static/' + +# URL prefix for admin static files -- CSS, JavaScript and images. +# Make sure to use a trailing slash. +# Examples: "http://foo.com/static/admin/", "/static/admin/". +ADMIN_MEDIA_PREFIX = '/static/admin/' + +# Additional locations of static files +STATICFILES_DIRS = ( + # Put strings here, like "/home/html/static" or "C:/www/django/static". + # Always use forward slashes, even on Windows. + # Don't forget to use absolute paths, not relative paths. +) + +# List of finder classes that know how to find static files in +# various locations. +STATICFILES_FINDERS = ( + 'django.contrib.staticfiles.finders.FileSystemFinder', + 'django.contrib.staticfiles.finders.AppDirectoriesFinder', +# 'django.contrib.staticfiles.finders.DefaultStorageFinder', +) + +# Make this unique, and don't share it with anybody. +SECRET_KEY = 'tdzq9m9k-u*k=furpki(@wejb&^2!ea4*z1^t9waj&$)(+$4(h' + +# List of callables that know how to import templates from various sources. +TEMPLATE_LOADERS = ( + 'django.template.loaders.filesystem.Loader', + 'django.template.loaders.app_directories.Loader', +# 'django.template.loaders.eggs.Loader', +) + +MIDDLEWARE_CLASSES = ( + 'django.middleware.common.CommonMiddleware', + 'django.contrib.sessions.middleware.SessionMiddleware', + 'django.middleware.csrf.CsrfViewMiddleware', + 'django.contrib.auth.middleware.AuthenticationMiddleware', + 'django.contrib.messages.middleware.MessageMiddleware', +) + +ROOT_URLCONF = 'libcloud_project.urls' + +TEMPLATE_DIRS = ( + # Put strings here, like "/home/html/django_templates" or "C:/www/django/templates". + # Always use forward slashes, even on Windows. + # Don't forget to use absolute paths, not relative paths. +) + +INSTALLED_APPS = ( + 'django.contrib.auth', + 'django.contrib.contenttypes', + 'django.contrib.sessions', + 'django.contrib.sites', + 'django.contrib.messages', + 'django.contrib.staticfiles', + # Uncomment the next line to enable the admin: + # 'django.contrib.admin', + # Uncomment the next line to enable admin documentation: + # 'django.contrib.admindocs', +) + +# A sample logging configuration. The only tangible logging +# performed by this configuration is to send an email to +# the site admins on every HTTP 500 error. +# See http://docs.djangoproject.com/en/dev/topics/logging for +# more details on how to customize your logging configuration. +LOGGING = { + 'version': 1, + 'disable_existing_loggers': False, + 'handlers': { + 'mail_admins': { + 'level': 'ERROR', + 'class': 'django.utils.log.AdminEmailHandler' + } + }, + 'loggers': { + 'django.request': { + 'handlers': ['mail_admins'], + 'level': 'ERROR', + 'propagate': True, + }, + } +} + +# +# Specific project configuration +# +from libcloud.storage.types import Provider +LIBCLOUD_PROVIDERS = { + 'test_google_storage': { + 'type': Provider.GOOGLE_STORAGE, + 'user': '<google apiv1 user (20 char)>', + 'key': '<google apiv1 key>', + 'bucket': '<bucket name>' + } +} + +DEFAULT_FILE_STORAGE = 'backends.backends.LibCloudStorage'
\ No newline at end of file diff --git a/examples/libcloud_project/test_storage.py b/examples/libcloud_project/test_storage.py new file mode 100644 index 0000000..18d1b72 --- /dev/null +++ b/examples/libcloud_project/test_storage.py @@ -0,0 +1,14 @@ +import sys, os +PROJECT_PATH = os.path.dirname(os.path.abspath(__file__)) +sys.path.append(PROJECT_PATH) + +from django.core.management import setup_environ +import settings +setup_environ(settings) + +from storages.backends.apache_libcloud import LibCloudStorage + +# test_google_storage is a key in settings LIBCLOUD_PROVIDERS dict +store = LibCloudStorage('test_google_storage') +# store is your django storage object that will use google storage +# bucket specified in configuration
\ No newline at end of file diff --git a/examples/libcloud_project/urls.py b/examples/libcloud_project/urls.py new file mode 100644 index 0000000..3eaf5ab --- /dev/null +++ b/examples/libcloud_project/urls.py @@ -0,0 +1,17 @@ +from django.conf.urls.defaults import patterns, include, url + +# Uncomment the next two lines to enable the admin: +# from django.contrib import admin +# admin.autodiscover() + +urlpatterns = patterns('', + # Examples: + # url(r'^$', 'libcloud_project.views.home', name='home'), + # url(r'^libcloud_project/', include('libcloud_project.foo.urls')), + + # Uncomment the admin/doc line below to enable admin documentation: + # url(r'^admin/doc/', include('django.contrib.admindocs.urls')), + + # Uncomment the next line to enable the admin: + # url(r'^admin/', include(admin.site.urls)), +) diff --git a/examples/s3project/__init__.py b/examples/s3project/__init__.py new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/examples/s3project/__init__.py diff --git a/examples/s3project/manage.py b/examples/s3project/manage.py new file mode 100644 index 0000000..77c9127 --- /dev/null +++ b/examples/s3project/manage.py @@ -0,0 +1,15 @@ +# put patched django and S3 in PYTHONPATH +import sys, os +sys.path = [os.path.join(os.getcwd(), '../../')] + sys.path + +from django.core.management import execute_manager + +try: + import settings # Assumed to be in the same directory. +except ImportError: + import sys + sys.stderr.write("Error: Can't find the file 'settings.py' in the directory containing %r. It appears you've customized things.\nYou'll have to run django-admin.py, passing it your settings module.\n(If the file settings.py does indeed exist, it's causing an ImportError somehow.)\n" % __file__) + sys.exit(1) + +if __name__ == "__main__": + execute_manager(settings) diff --git a/examples/s3project/models.py b/examples/s3project/models.py new file mode 100644 index 0000000..0a4815d --- /dev/null +++ b/examples/s3project/models.py @@ -0,0 +1,25 @@ + +import tempfile + +from django.db import models +from django.core.files.base import ContentFile +from django.core.files.storage import default_storage as s3_storage +from django.core.cache import cache + +# Write out a file to be used as default content +s3_storage.save('tests/default.txt', ContentFile('default content')) + +class MyStorage(models.Model): + def custom_upload_to(self, filename): + return 'foo' + + def random_upload_to(self, filename): + # This returns a different result each time, + # to make sure it only gets called once. + import random + return '%s/%s' % (random.randint(100, 999), filename) + + normal = models.FileField(storage=s3_storage, upload_to='tests') + custom = models.FileField(storage=s3_storage, upload_to=custom_upload_to) + random = models.FileField(storage=s3_storage, upload_to=random_upload_to) + default = models.FileField(storage=s3_storage, upload_to='tests', default='tests/default.txt') diff --git a/examples/s3project/settings.py b/examples/s3project/settings.py new file mode 100644 index 0000000..3ac8133 --- /dev/null +++ b/examples/s3project/settings.py @@ -0,0 +1,52 @@ +import os +ROOT_PATH = os.path.dirname(__file__) + +TEMPLATE_DEBUG = DEBUG = True +MANAGERS = ADMINS = () +DATABASE_ENGINE = 'sqlite3' +DATABASE_NAME = os.path.join(ROOT_PATH, 'testdb.sqlite') + +TIME_ZONE = 'America/Chicago' +LANGUAGE_CODE = 'en-us' +SITE_ID = 1 +USE_I18N = True +MEDIA_ROOT = '' +MEDIA_URL = '' +ADMIN_MEDIA_PREFIX = '/media/' +SECRET_KEY = '2+@4vnr#v8e273^+a)g$8%dre^dwcn#d&n#8+l6jk7r#$p&3zk' +TEMPLATE_LOADERS = ( + 'django.template.loaders.filesystem.load_template_source', + 'django.template.loaders.app_directories.load_template_source', +) +MIDDLEWARE_CLASSES = ( + 'django.middleware.common.CommonMiddleware', + 'django.contrib.sessions.middleware.SessionMiddleware', + 'django.contrib.auth.middleware.AuthenticationMiddleware', +) +ROOT_URLCONF = 'urls' +TEMPLATE_DIRS = (os.path.join(ROOT_PATH, 'templates'),) +INSTALLED_APPS = ( + 's3project', # ugly but easier + 'django.contrib.auth', + 'django.contrib.contenttypes', + 'django.contrib.sessions', + 'django.contrib.sites', +) + +DEFAULT_FILE_STORAGE = 'backends.S3Storage.S3Storage' + +from S3 import CallingFormat +AWS_CALLING_FORMAT = CallingFormat.SUBDOMAIN +AWS_HEADERS = { + 'Expires': 'Thu, 15 Apr 2010 20:00:00 GMT', # see http://developer.yahoo.com/performance/rules.html#expires + 'Cache-Control': 'max-age=86400', + } + +# local_settings.py can be used to override environment-specific settings +# like database and email that differ between development and production. +# Add you custom AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY and +# AWS_STORAGE_BUCKET_NAME settings +try: + from local_settings import * +except ImportError: + pass diff --git a/examples/s3project/tests.py b/examples/s3project/tests.py new file mode 100644 index 0000000..d849b20 --- /dev/null +++ b/examples/s3project/tests.py @@ -0,0 +1,200 @@ +""" +================= +Django S3 storage +================= + +Usage +===== + +Settings +-------- + +``DEFAULT_FILE_STORAGE`` +~~~~~~~~~~~~~~~~~~~~~~~~ + +This setting store the path to the S3 storage class, the first part correspond +to the filepath and the second the name of the class, if you've got +``example.com`` in your ``PYTHONPATH`` and store your storage file in +``example.com/libs/storages/S3Storage.py``, the resulting setting will be:: + + DEFAULT_FILE_STORAGE = 'libs.storages.S3Storage.S3Storage' + +If you keep the same filename as in repository, it should always end with +``S3Storage.S3Storage``. + +``AWS_ACCESS_KEY_ID`` +~~~~~~~~~~~~~~~~~~~~~ + +Your Amazon Web Services access key, as a string. + +``AWS_SECRET_ACCESS_KEY`` +~~~~~~~~~~~~~~~~~~~~~~~~~ + +Your Amazon Web Services secret access key, as a string. + +``AWS_STORAGE_BUCKET_NAME`` +~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Your Amazon Web Services storage bucket name, as a string. + +``AWS_CALLING_FORMAT`` +~~~~~~~~~~~~~~~~~~~~~~ + +The way you'd like to call the Amazon Web Services API, for instance if you +prefer subdomains:: + + from S3 import CallingFormat + AWS_CALLING_FORMAT = CallingFormat.SUBDOMAIN + +``AWS_HEADERS`` (optionnal) +~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +If you'd like to set headers sent with each file of the storage:: + + # see http://developer.yahoo.com/performance/rules.html#expires + AWS_HEADERS = { + 'Expires': 'Thu, 15 Apr 2010 20:00:00 GMT', + 'Cache-Control': 'max-age=86400', + } + + +Fields +------ + +Once you're done, ``default_storage`` will be the S3 storage:: + + >>> from django.core.files.storage import default_storage + >>> print default_storage.__class__ + <class 'backends.S3Storage.S3Storage'> + +This way, if you define a new ``FileField``, it will use the S3 storage:: + + >>> from django.db import models + >>> class Resume(models.Model): + ... pdf = models.FileField(upload_to='pdfs') + ... photos = models.ImageField(upload_to='photos') + ... + >>> resume = Resume() + >>> print resume.pdf.storage + <backends.S3Storage.S3Storage object at ...> + + +Tests +===== + +Initialization:: + + >>> from django.core.files.storage import default_storage + >>> from django.core.files.base import ContentFile + >>> from django.core.cache import cache + >>> from models import MyStorage + +Storage +------- + +Standard file access options are available, and work as expected:: + + >>> default_storage.exists('storage_test') + False + >>> file = default_storage.open('storage_test', 'w') + >>> file.write('storage contents') + >>> file.close() + + >>> default_storage.exists('storage_test') + True + >>> file = default_storage.open('storage_test', 'r') + >>> file.read() + 'storage contents' + >>> file.close() + + >>> default_storage.delete('storage_test') + >>> default_storage.exists('storage_test') + False + +Model +----- + +An object without a file has limited functionality:: + + >>> obj1 = MyStorage() + >>> obj1.normal + <FieldFile: None> + >>> obj1.normal.size + Traceback (most recent call last): + ... + ValueError: The 'normal' attribute has no file associated with it. + +Saving a file enables full functionality:: + + >>> obj1.normal.save('django_test.txt', ContentFile('content')) + >>> obj1.normal + <FieldFile: tests/django_test.txt> + >>> obj1.normal.size + 7 + >>> obj1.normal.read() + 'content' + +Files can be read in a little at a time, if necessary:: + + >>> obj1.normal.open() + >>> obj1.normal.read(3) + 'con' + >>> obj1.normal.read() + 'tent' + >>> '-'.join(obj1.normal.chunks(chunk_size=2)) + 'co-nt-en-t' + +Save another file with the same name:: + + >>> obj2 = MyStorage() + >>> obj2.normal.save('django_test.txt', ContentFile('more content')) + >>> obj2.normal + <FieldFile: tests/django_test_.txt> + >>> obj2.normal.size + 12 + +Push the objects into the cache to make sure they pickle properly:: + + >>> cache.set('obj1', obj1) + >>> cache.set('obj2', obj2) + >>> cache.get('obj2').normal + <FieldFile: tests/django_test_.txt> + +Deleting an object deletes the file it uses, if there are no other objects +still using that file:: + + >>> obj2.delete() + >>> obj2.normal.save('django_test.txt', ContentFile('more content')) + >>> obj2.normal + <FieldFile: tests/django_test_.txt> + +Default values allow an object to access a single file:: + + >>> obj3 = MyStorage.objects.create() + >>> obj3.default + <FieldFile: tests/default.txt> + >>> obj3.default.read() + 'default content' + +But it shouldn't be deleted, even if there are no more objects using it:: + + >>> obj3.delete() + >>> obj3 = MyStorage() + >>> obj3.default.read() + 'default content' + +Verify the fix for #5655, making sure the directory is only determined once:: + + >>> obj4 = MyStorage() + >>> obj4.random.save('random_file', ContentFile('random content')) + >>> obj4.random + <FieldFile: .../random_file> + +Clean up the temporary files:: + + >>> obj1.normal.delete() + >>> obj2.normal.delete() + >>> obj3.default.delete() + >>> obj4.random.delete() + +"""
\ No newline at end of file |
