Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Files in Django

Sponsored · Ship Features Fearlessly Turn features on and off without deploys. Used by thousands of Ruby developers.

Files in Django

Avatar for Josh Schneier

Josh Schneier

August 16, 2017
Tweet

More Decks by Josh Schneier

Other Decks in Programming

Transcript

  1. ME INTRODUCTION ▸ Using Django since 1.3 — have mentored

    and onboarded a number of junior developers since then ▸ Maintainer of django-storages ▸ Talk will proceed in 3 parts: ▸ Overview of the API provided by Django ▸ Some options for deployment ▸ Writing a storage backend
  2. API OVERVIEW STATIC & MEDIA FILES ▸ STATIC files are

    the other types of files that make up your application (e.g. CSS, JavaScript and images) ▸ MEDIA files are user uploaded files ▸ This distinction has ramifications but there are similarities as well: ▸ STATIC files might come from other 3rd party applications ▸ MEDIA files come from unknown (as well as admin) users — they don’t have the same trust model ▸ Both need to be stored somewhere and then subsequently served to users
  3. API OVERVIEW STATIC FILES ▸ Used by django.contrib.staticfiles ▸ A

    number of settings: STATIC_ROOT, STATIC_URL, STATICFILES_DIRS, STATICFILES_STORAGE, STATICFILES_FINDERS ▸ In development (when using runserver) files are served automatically by django.contrib.staticfiles.views.serve ▸ Docs are very explicit — will refuse to run unless DEBUG = True (will talk production deployments soon) ▸ All comes together with collectstatic
  4. API OVERVIEW MEDIA FILES ▸ A lot more settings: DEFAULT_FILE_STORAGE,

    FILE_CHARSET, FILE_UPLOAD_HANDLERS, FILE_UPLOAD_MAX_MEMORY_SIZE, FILE_UPLOAD_TEMP_DIR, FILE_UPLOAD_DIRECTORY_PERMISSIONS, FILE_UPLOAD_PERMISSIONS, MEDIA_ROOT, MEDIA_URL ▸ Having both MEDIA_ROOT & MEDIA_URLwas a bit confusing for me at first — they are analogous to STATIC_ROOT & STATIC_URL ▸ MEDIA files are not automatically served in development ▸ I include a snippet in all of my projects (taken from the docs) in development to handle this: if settings.DEBUG: urlpatterns += static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
  5. API OVERVIEW STORAGE ▸ The major unifier is that they

    are stored with the same API — subclasses of django.core.files.storage.Storage ▸ Core ships with FileSystemStorage ▸ Fairly straightforward interface defined _open _save delete exists listdir size url path get_valid_name get_available_name get_accessed_time get_created_time get_modified_time
  6. API OVERVIEW FILES ▸ Generally working with a django.core.files.File ▸

    Thin wrapper over a native file ▸ Mostly commonly seen when working with ImageField & FileField ▸ Can specify which storage to use instead of the DEFAULT_FILE_STORAGE with storage=…
  7. DEPLOYMENT STATIC FILE SERVING ▸ We definitely shouldn’t use runserver

    to serve our files — so what’s next? ▸ We also want all the production must-haves e.g. caching headers and compression ▸ One option is to have whatever is doing your reverse proxying (nginx, apache, etc) handle this for you
  8. DEPLOYMENT STATIC FILE SERVING CONT. ▸ Pros: ▸ Reduced load

    on your Django process ▸ Using a tool that is highly optimized for this exact task ▸ Cons: ▸ Need to have access to said reverse proxy — not always possible e.g. Heroku ▸ Fiddly and annoying configuration — hard to get right and easy to get wrong
  9. DEPLOYMENT STATIC FILE SERVING CONT. ▸ Another possibility, that I’d

    recommend for most sites, is to use whitenoise ▸ Extremely easy to install and configure in pure Python ▸ Includes a ton of features such as gzip, brotli, hashed files, and caching headers ▸ Then put it behind a CDN such as Cloudfront and your hits to Python will be minimal — only when new content is uploaded ▸ Would not recommend serving static files out of S3 generally
  10. DEPLOYMENT MEDIA FILE SERVING ▸ In this case you should

    not be serving your files off of the same domain as your application ▸ Untrusted content being downloaded and executed in the context of your user’s session is dangerous — same-origin policy to the rescue ▸ Use a dedicated host (and domain) or host in the cloud for scaling and redundancy ▸ Many options exist and more seem to be pop up all the time ▸ Use a library to deal with the tricky bits — I recommend django-storages ▸ Can still use a CDN
  11. DEMO, ERR FUN! LET’S WRITE A STORAGE BACKEND ▸ Going

    to use IPFS ▸ Interplanetary File System ▸ Distributed (P2P) content-addressable versioned immutable storage ▸ AKA super cool