django static files versioning

后端 未结 10 1047
伪装坚强ぢ
伪装坚强ぢ 2021-01-30 21:26

I\'m working on some universal solution for problem with static files and updates in it.

Example: let\'s say there was site with /static/styles.css file - a

相关标签:
10条回答
  • 2021-01-30 21:58

    Django 1.4 now includes CachedStaticFilesStorage which does exactly what you need (well... almost).

    Since Django 2.2 ManifestStaticFilesStorage should be used instead of CachedStaticFilesStorage.

    You use it with the manage.py collectstatic task. All static files are collected from your applications, as usual, but this storage manager also creates a copy of each file with the MD5 hash appended to the name. So for example, say you have a css/styles.css file, it will also create something like css/styles.55e7cbb9ba48.css.

    Of course, as you mentioned, the problem is that you don't want your views and templates calculating the MD5 hash all the time to find out the appropriate URLs to generate. The solution is caching. Ok, you asked for a solution without caching, I'm sorry, that's why I said almost. But there's no reason to reject caching, really. CachedStaticFilesStorage uses a specific cache named staticfiles. By default, it will use your existing cache system, and voilà! But if you don't want it to use your regular cache, perhaps because it's a distributed memcache and you want to avoid the overhead of network queries just to get static file names, then you can setup a specific RAM cache just for staticfiles. It's easier than it sounds: check out this excellent blog post. Here's what it would look like:

    CACHES = {
      'default': {
        'BACKEND': 'django.core.cache.backends.memcached.PyLibMCCache',
        'LOCATION': '127.0.0.1:11211',
      },
      'staticfiles': {
        'BACKEND': 'django.core.cache.backends.locmem.LocMemCache',
        'LOCATION': 'staticfiles-filehashes'
      }
    }
    
    0 讨论(0)
  • 2021-01-30 21:59

    How about you always have a URL Parameter in your URL with a version and whenever you have a major release you change the version in your URL Parameter. Even in the DNS. So if www.yourwebsite.com loads up www.yourwebsite.com/index.html?version=1.0 then after the major release the browser should load www.yourwebsite.com/index.html?version=2.0

    I guess this is similar to your solution 1. Instead of tracking files can you track whole directories? For example ratehr than /static/style/css?v=2.0 can you do /static-2/style/css or to make it even granular /static/style/cssv2/.

    0 讨论(0)
  • 2021-01-30 22:04

    I use a global base context in all my views, where I set the static version to be the millisecond time (that way, it will be a new version every time I restart my application):

    # global base context
    base_context = {
        "title": settings.SITE_TITLE,
        "static_version": int(round(time.time() * 1000)),
    }
    
    # function to merge context with base context
    def context(items: Dict) -> Dict:
        return {**base_context, **items}
    
    # view
    def view(request):
        cxt = context({<...>})
        return render(request, "page.html", cxt)
    

    my page.html extends my base.html template, where I use it like this:

    <link rel="stylesheet" type="text/css" href="{% static 'style.css' %}?v={{ static_version }}">
    

    fairly simple and does the job

    0 讨论(0)
  • 2021-01-30 22:06

    I use my own templatetag which add file modification date to url: https://bitbucket.org/ad3w/django-sstatic

    0 讨论(0)
提交回复
热议问题