Django: caching images - django

I am currently using django-compressor which provides great benefits by caching compressed CSS and JS files.
Now I would like to cache images. I know that browser caching can be enabled using HTTP headers (downstream caching) but I would like to use Redis here (it is already used by django-compressor).
So this is my first question: is it right to cache images with Redis?
I have read interesting things about sorl-thumbnail and its caching through the thumbnail template tag. I thought maybe I could use it in a raw way but the tag requires a geometry argument.
Is there an existing Django package I could use to cache images? Should I write a template tag similar to sorl-thumbnail's thumbnail tag to enable image caching by using Django's built-in cache?

This is not a job for redis and isn't a good use case for django. If you want to cache images in memory to serve from the server, front your django app server (like uwsgi or gunicorn) and nginx and use varnish to cache the images in memory. Redis does not do great for storing/retrieving large blobs.

Related

Push media files to a seperate nginx VM with Django in production

I don't know if I missed information regarding this. But I want to know how to store static files to a different VM. I've read that some recommend doing that to larger sites to seperate the load.
My current setup is that I use one computer engine with nginx, virtualenv, gunicorn etc. I use nginx to display the static files (including the media files) on the same server.
How can I push media files to a seperate nginx server when a user uploads an image? How can I obtain the same url as well?
Let's first explore the options of static resources(Javascript, CSS, Images, Fonts etc...)
You have complete control of where this static content should go during the deployment. Typically these resources will go for compression during the build process to optimize the content size to reduce the bandwidth.
Deploy the static resource on the different server(VM with ngnix) and configure that URL in the Django settings.py with STATIC_URL. If you use the cookieless domain, it will save little more bandwidth. Refer the section Use Cookie-free Domains for Components in this URL: https://developer.yahoo.com/performance/rules.html
You can use the content expiry settings for these resources to cache on the client for the specified duration.
Some best practices are mentioned in the official documentation: https://docs.djangoproject.com/en/1.10/howto/static-files/
For the media resources, you can save the files on the shared volume and run it on the different server same as static resources. You can configure that server URL in the Django settings.py with MEDIA_URL.

Content negotiation with Django staticfiles in runserver

I'm managing static files (JS, CSS, images, etc) in my Django application using staticfiles. This works fine, but I'd like to start dynamically serving pre-compressed sources when the user's browser is capable.
I went through the linked tutorial and, in production (on Apache) this works fine. I can include files using
<script src="/static/js/my-site"></script>
and it will load my-site.js in older browsers and my-site.js.gz when GZip encoding is supported. Great! But: this breaks local development using runserver. Of course, the staticfiles default view has no idea how to turn /js/my-site into /js/my-site.js (or .gz). To get runserver working, I need to specify the extension, which breaks content negotiation.
Is there a better way to configure Apache, so that I can always request .js (or .css, etc) and get served the compressed version transparently? Or can I tell Django how to find the requested resource without specifying an extension? I wouldn't think I'm the only one trying to do this...
there is no simple resolution. mostly because you are using something that was designed for the apache web server only (afaik).
i my opinion there are 3 solutions:
keep source .{js,css} files in separate directory, in development you can serve them from source dir or compressed one - simple, transparent and you can hide your uncompressed and non-obfuscated sources far from the reach
compress files with the .min.{js,css} ending - no need for separate directory, you can hide sources in apache (mod_rewrite)
write your own small middleware that will be simulating what apache does (it is few lines to select and rewrite path, you can even have different behavior depending on DEBUG config var)
use some dynamic solution e.g Django Compressor which will compile those files on-demand
(I'm using option 4 :) )

How much of a performance boost I can get by using nginx on top of Django CMS?

The static page content comes from Django CMS which makes it dynamic , How is using nginx in such a scenario beneficial ?
It is generally considered a best practice to have "static" content served by a traditional web server such as Nginx or Apache. By static content, I am referring to things like CSS, JavaScript, and Images. Since these files often don't require modification between requests, there is little sense in having Django serve them. And Nginx/Apache can be serving these files to the client's browser concurrently.
However, your dynamic content served by Django needs to be rendered within the context of one or more Django templates. Not to mention, content such as blog posts needs to be retrieved from the database. Fortunately, Django has a robust caching system that you can use to cache the rendered HTML output and decrease server load and response times.
How much of a performance boost you gain really depends on the situation. I can tell you from experience that caching a complex response has reduced the response time from 300ms down to 30ms in one scenario.
EDIT: Adding a great article on Scaling Django: Caching and Static Content.

Mixing django-filepicker and mongodb

I'm developing a django 1.4 application, and I'm using django-filepicker to upload images. They use a special modelField for images called FPFileField.
I'm interested in storing those images in a MongoDB database, instead of uploading it to a "media" folder or something similar.
Any idea how this can be achieved?
I've tried mongoengine with no luck.
I would recommend storing the url into your mongo Document directly and then making use of the filepicker.io URL and built in S3 support rather than storing the file on your servers directly.
You should look into GridFS
I'd also consider uploading it to amazon's S3 service too - depending on what your requirements are.

mod_deflate vs Django GZipMiddleware, which one to use for deployment?

We're deploying Django apps with Apache 2.2 + mod_wsgi. Should we enable mod_deflate in Apache or use Django's GZipMiddleware? Which option performs better?
You should probably test to know for sure, but if I were to guess, mod_deflate would be better for requests that totally bypass Django completely (like zipped up static resources that should be deployed separately i.e. media).
For things that are already generated by Django responses, it's probably a toss-up -- in either case it would be native code doing the zipping.
It depends. If you enable it in Apache, then it will also be used for static content (e.g. CSS, Javascript, images); but some static content (like JPG, GIF, SWF) is pretty well compressed anyway.
mod_deflate is a better choice because it allows you to choose which content types are compressed (defaults to html, css and js).
GZipMiddleware is very naive and will try to compress anything and just check if the result is smaller than the original response. If you're serving images that way you will take the performance hit for each request with 0 benefit.
I would definitely go with mod_deflate, on the assumption that you have static css and js files which apache is serving directly and can also be compressed.