Django : Is it a good idea to generate JS dynamica

2019-03-11 14:49发布

问题:

When I write my JS files for a Django project, of course I do some AJAX calls, and for the moment the urls for those calls are hard-coded (which is very ugly).

I was thinking of having the JS files served by django (instead of Apache), so I could take advantage of the template tags ({% url %} !!!).

Is there a reason why I shouldn't do this ?

Or is there a right way to do this ?

(I can give a least one : it will consume a lot of time resending JS files that haven't changed. What would be great is to have an application that generates files when restarting django server, and serves them statically after !)

回答1:

I would go for a hybrid technique. Serve most of your javascript statically. But in your Django template, have a <script> block that defines various global variables, which are generated by the server-side code - url is a good example. Then your static JS can refer to the variables that are generated in the dynamic code.



回答2:

I searched deeper in those asset manager applications from djangopackages, have found out that django-mediagenerator provides that feature, even if it is not well documented : you can generate your js or css files as django templates, and then serve them statically (they are also bundled, and caching is managed etc ... so two birds with one stone + it is really easy to set-up !).

In order to have JS files generated as django templates (after having set-up django-mediagenerator), just add the filter :

ROOT_MEDIA_FILTERS = {
    'js': 'mediagenerator.filters.template.Template',
}

in your settings.



回答3:

Dynamically generating Javascript on your server can be a tremendously powerful tool and I've experienced both it's upside and downside in my projects.

In general you want to keep as much as possible static to minimize the work to be done on every request. This includes having the browser cache as much as possible, which might become a problem in your case.

What I usually do is to have a block in the header in my base template. In templates that need to do custom javascript that is only known at runtime (customization based on logged in user, for example), I add it to the block. Here I can dynamically generate javascript that I know won't be cached so I can make some assumptions. The downside is more complexity.

If what you need are just pointing to urls, or have some simple configuration, etc, then I would suggest creating a view that will return a Javascript file with these settings. You can set the correct headers(Etag, Cache-Control, etc) so the browser will cache the file for some reasonable time. When you upgrade your code, make sure the Etag will change.

In the code that needs to use the configuration, you need to always check that the variable you are looking for is actually defined otherwise you will run into problems that are hard to debug when for some reason the configuration javascript is not loaded correctly.



回答4:

The .js that gets sent to the browser would vary. That could make debugging more cumbersome. Maybe not a problem but something to potentially consider...



回答5:

Nowadays, the best way to do this is to use Django.js

Here is the doc where they talk about the URL reversing: http://djangojs.readthedocs.org/en/0.8.1/djangojs.html#reverse-urls