Django: Cache-Control: max-age. How to specify? What is cached? - django

I'm making a webpage and ideally I'd like the user's browser to cache all javascript, css, and images forever (or the max allowed 1 year). These items are either versioned or they do not change. However, I do not want the html to be cached.
I'm confused about Cache-Control: max-age. Do I set this for each type of resource (css, js, etc)? Or once for everything? Or for specific files? Will it cache the html?
I'm using Django. Where would I even specify it:
return render_to_response(my_template, {},context_instance=RequestContext(request))
I've noticed that my browser (I've tried several) caches images and js even though I have not specified anything. But can I depend on this always? And for how long will it be cached?

You need to set this header on individual static files. However you should not be serving static files from Django in production. Use a web server such as Nginx, Lighttpd for that, or better yet, a CDN.

Related

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.

Django: How to use static files (simple case, jquery)

I am trying to use jQuery on a Django site. I need to include the jQuery.js library. I have read a lot about Django static files, but I don't think anyone has asked this particular question. I have only three static files to serve: jquery.js, anothersmallfile.js, and styles.css. The Django docs on static file serving say:
"For small projects, this isn’t a big deal, because you can just keep the static files somewhere your web server can find it. link
I would like to "just keep them somewhere my webserver can find them" because elsewhere the Django docs clearly state (warn) that their static-files serving method is only for a development environment. I only have a few static files and I just want the simplest secure solution.
Unfortunately I can't get it working. No matter where I put the files, Django can't find them. Debugging through Chrome web developer console I see I'm getting a 404 error:
GET http://127.0.0.1:8000/templates/polls/jquery.js 404 (NOT FOUND)
I am new to running a server. Do I A.) need to tell my urls.py file where to find static files? or perhaps the problem is B.) that I have misunderstood this issue - Django is my webserver (for production) so right now I must use the Django static files solution?
Doesn't seem like it ought to be very difficult to get my templates to simply recognize a .js file that's in the same directory as they are. Am I missing something?
Edit, before I get more downvotes: I am talking about this passage from the page linked above:
///////////////////////
Django developers mostly concern themselves with the dynamic parts of web applications – the views and templates that render anew for each request. But web applications have other parts: the static files (images, CSS, Javascript, etc.) that are needed to render a complete web page.
For small projects, this isn’t a big deal, because you can just keep the static files somewhere your web server can find it. However, in bigger projects – especially those comprised of multiple apps – dealing with the multiple sets of static files provided by each application starts to get tricky.
That’s what django.contrib.staticfiles is for: it collects static files from each of your applications (and any other places you specify) into a single location that can easily be served in production.
///////////////////
Emphasis added
So if that's what django.contrib.staticfiles is for, what's the simpler solution? I dispute that this is a repeat of prior questions.
You need to read that documentation more closely. That warning is for production. In development, you do use that static-serving method, ie putting it in your urls.py. And, that documentation will also show that the templates directory is not the right place to put them: a separate static or media directory is.
Edit after comment I really don't understand your comment. Either you do it in development via the static serving view, or you use your production server. But you say you don't have a production server. When you get one, whether it's Apache or Nginx or whatever, you put your static files in a directory and tell that server to serve files from there. That is the simple solution. The staticfiles app, exactly as in the docs you quoted, are for when you've got lots of files in different apps (and it simplifies the move from development to production, not complicates it as you seem to think).
Suppose your app is www.
setting.py -> STATIC_ROOT = 'static/'
make dir www/static
make file www/static/some.html
in browser localhost:8000/static/some.html
That's all.

Django where to put static files

I am using Django to create a small web app, however I do not know where i must put my HTML and JS files. I don't want to use the templateing system because I have no need to pass the values from Django directly to the HTML template, Instead the HTML will be static and I will fetch all the data necessary and send the data to be input back into the database using AJAX with Jquery.
My Question is where must I put my HTMl and JS files so they are accessible from the web browser and will be in the same directory so that I can send my ajax requests to something like
http://localhost:2000/webapp/RPC/updateitem/ (more stuff here)
and where the HTML files are
http://localhost:2000/webapp/index.html
Thanks,
RayQuang
You let your main webserver (the one you're running django on) deal with the static files. In most cases this means that you simly server the files through apache (or lighttpd or cherrypy or whatever). Django is only ment for the rendering of dynamic things and thus should not be used for serving static files.
If you're running from a development server (which I can't recommend), this tutorial will help you through setting it up: Serving static files

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.