""" ================= 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__ 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 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 >>> 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 >>> 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 >>> 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 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 Default values allow an object to access a single file:: >>> obj3 = MyStorage.objects.create() >>> obj3.default >>> 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 Clean up the temporary files:: >>> obj1.normal.delete() >>> obj2.normal.delete() >>> obj3.default.delete() >>> obj4.random.delete() """