[Django]static 파일 캐시 처리하기

reowjd·2021년 1월 19일
2

Django 시리즈

목록 보기
3/5
post-thumbnail

유지 보수 작업을 하고 서버에 배포 했는데, 정적(static) 파일(js, css..)들이 바로 반영되지 않는 이슈가 있다. 그 이유는 파일들이 캐시 처리되었기 때문이다. 캐시된 파일들은 로컬에서 가져오기 때문에 서버에 배포해도 반영되지 않는다. 이 문제를 해결하기 위해서는 새로운 파일이라는 표시를 해주어야 한다. 아래와 같이 파라미터를 추가하면 캐시된 파일을 사용하지 않고 서버에서 가져온다.

<script src="https://static.velog.io/static/js/20.c4f442fa.chunk.js?v=<RANDOM_NUM>👈"></script>

배포 시마다<RANDOM_NUM>을 달리하면, 캐시로 인해 반영되지 않는 문제를 해결할 수 있다.

그렇다면 장고에서는 이 처리를 어떻게 하는게 좋을까? 새로운 정적 파일을 로드할 때마다 파라미터를 추가할 수도 있지만, 장고에서 제공하는 tempatetags와 템플릿 태그인 {% static %}을 사용하면 좀 더 간단하게 해결할 수 있다. {% static %} 태그를 사용하여 파일을 로드하면 자동으로 파라미터가 붙도록 작업할 것이다.
이 작업은 정적 파일을 아래와 같이 {% static %} 태그로 로드한다는 전제가 필요하다.

<script src="{% static js/20.c4f442fa.chunk.js %}"><script>

templatetags

tempatetags는 장고에서 커스텀 템플릿 태그를 만들 때 사용한다. app 하위에 templatetags 폴더를 만들고 폴더 하위에 파일을 정의하면 된다.

.
├── app
│   ├── migrations
│   ├── templatetags 👈
│   └── views
│   ├── __init__.py
│   ├── admin.py
│   ├── apps.py
│   ├── models.py
├── djangoseries
│   ├── __init__.py
│   ├── __pycache__
│   ├── settings.py
│   ├── urls.py
│   └── wsgi.py
└── manage.py

{% static %} 템플릿 태그 커스텀하기

templatetags 폴더 하위에 static.py를 만든다. 그리고 아래와 같이 코드를 작성한다.

#templatetags/static.py

from django import template
from django.templatetags.static import StaticNode
register = template.Library()

class CustomStaticNode(StaticNode):
    def url(self, context):
        version = #랜덤 값으로 하거나 날짜로 작업할 수 있음.
        path = f'{super().url(context)}?v={version}'
        return path


@register.tag('static')
def do_static(parser, token):
    node = CustomStaticNode.handle_token(parser, token)
    return node
  • register = template.Library() : Library에 등록하기 위해 register를 선언해야 한다.
  • @register.tag('static') : static태그 호출 시, 아래 함수를 호출하고 결과를 반환한다.
    ** 코드 출처

코드는 단순한데, 장고에서 기본적으로 제공하는 static 태그의 StaticNode 클래스를 상속 받아 CustomStaticNode로 재정의 하는 것이다. 부모 url() 메서드의 url을 받고 ?v={version}를 추가해서 새로 반환한다.

StaticNodeurl()메서드는 아래와 같다.

class StaticNode(template.Node):
	...
    def url(self, context):
        path = self.path.resolve(context)
        return self.handle_simple(path)

그리고 기존 static 태그는 아래와 같이 태그를 등록하였다.

@register.tag('static')
def do_static(parser, token):
    """
    Join the given path with the STATIC_URL setting.
    Usage::
        {% static path [as varname] %}
    Examples::
        {% static "myapp/css/base.css" %}
        {% static variable_with_path %}
        {% static "myapp/css/base.css" as admin_base_css %}
        {% static variable_with_path as varname %}
    """
    return StaticNode.handle_token(parser, token)

마찬가지로, 기존 static 등록 코드에서 StaticNode 대신, CustomStaticNode로 변경해 주면 된다!

파라미터 값의 경우, 호출할 때마다 값이 바뀌면 파일 변경이 없어도 서버에서 파일을 계속 새로 받기 때문에 날짜로 하거나 다른 파일에 파라미터 값을 따로 관리하는 방식을 추천하는 바이다.

끝!

profile
개발계발

0개의 댓글