장고 시작하기 4. 장고 화면 꾸미기 기초 (장고 static 파일 관리)

들어가며

CSS, 글꼴, 이미지 파일, 자바스크립트 파일 등 웹 사이트를 꾸미기 위한 정적 파일들을 있습니다. Django에서는 이런 파일들을 static 디렉토리에서 관리합니다. 이번 포스트에서는 “장고 static 파일 관리” 와 관련된 내용을 공부하고 정리해보았습니다.

장고 static 파일 관리

django에서는 CSS, JS, 이미지 파일을 static 디렉토리에 관리한다고 말씀드렸는데요. 이 static 디렉토리가 자동으로 생성되지 않습니다. ㅎㅎ

python manage.py startapp <app name> 와 같은 명령어를 입력해서 새로운 프로젝트를 추가해도 static 디렉토리가 생성되지 않고요.

때문에 static 디렉토리를 만들어줘야 합니다.

또한 static 디렉토리를 만든 후에, “이 디렉토리가 static 디렉토리다” 라는 것도 Django가 알 수 있도록 설정해줘야 합니다.

이제 이 과정에 대해 정리해볼건데요.

이런 static 디렉토리를 관리하는 방법이 2가지 방법이 있습니다.

작은 프로젝트라면 하나의 app에 하나의 static 디렉토리만 만들면 끝이지만 프로젝트가 커지는 경우, 각 app마다 static을 둘 수도 있고, 전역적인 static디렉토리를 둘 수도 있습니다.

작은 프로젝트만 우선 관심이 있다면 “static 파일 관리하기” 부분만 빠르게 읽으면 됩니다.

static 파일 관리하기

CSS 파일과 같은 정적 관리해주기 위해서는 디렉토리를 따로 만들어줘야 합니다.

그리고 settings.py 모듈의 STATIC_URL 변수에 static 파일을 넣을 위치를 지정해주어서 “Django 프레임워크에 static 파일들이 어디있다”라고 알려줘야 합니다.

STATIC_URL = 'static/'

static 파일 사용하기

static 디렉토리에 있는 CSS 파일이나 기타 정적인 파일들을 가져오기 위해서는 head.html에 다음 코드를 맨 위에 작성해줘야 합니다.

include, exclude를 사용하지 않고 template 구조가 달라서 head.html이 없다면 사용하는 html 파일 맨 위 상단에 해당 코드를 입력해주시면 됩니다.

{% load static %}

CSS 파일 가져오기

그리고 CSS 파일을 가져온다면 CSS 파일을 가져올지 link 태그를 적어줍니다

<!-- DEFAULT CSS LINK -->
  <link rel="stylesheet" type="text/css" href="{% static 'base.css' %}">

<link> 태그는 HTML에서 스타일시트와 같은 외부 리소스를 현재 HTML 문서에 연결하는 데 사용됩니다. 다음은 제공된 <link> 태그에 사용된 속성에 대한 분석입니다.

rel="stylesheet": 이 속성은 현재 문서와 링크된 리소스 간의 관계를 지정합니다. 이 경우 연결된 리소스가 스타일시트임을 나타냅니다.

type="text/css": 이 속성은 연결된 리소스의 유형을 지정합니다. 연결된 리소스가 CSS(Cascading Style Sheets) 파일임을 지정합니다.

HTML5 사양에서는 CSS 파일에 대해 type 속성을 생략할 수 있지만(“text/css”가 기본 유형이므로) 이를 명시적으로 지정하면 이전 브라우저와의 호환성이 보장됩답니다.

href="{% static 'base.css' %}: 이 속성은 연결된 리소스의 URL을 지정합니다.
저는 static 디렉토리에 base.css 파일을 만들었으므로 base.cess라고 코드에 적었습니다.

Bootstrap, Google font, CSS link를 사용한다면 전체 head.html은 아래와 같이 됩니다.

{% load static %}

<head>
  <meta charset="UTF-8" />
  <meta name="viewport" content="width=device-width, initial-scale=1.0" />
  <title>Comment page</title>
  <!-- BOOTSTRAP LINK -->
  <link
    href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/css/bootstrap.min.css"
    rel="stylesheet"
    integrity="sha384-QWTKZyjpPEjISv5WaRU9OFeRpok6YctnYmDr5pNlyT2bRjXh0JMhjY6hW+ALEwIH"
    crossorigin="anonymous"
  />

  <!-- GOOGLE FONT LINK -->
  <link rel="preconnect" href="https://fonts.googleapis.com" />
  <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />
  <link
    href="https://fonts.googleapis.com/css2?family=Workbench&display=swap"
    rel="stylesheet"
  />

  <!-- DEFAULT CSS LINK -->
  <link rel="stylesheet" type="text/css" href="{% static 'base.css' %}">
</head>

이미지 파일 가져오기

<img src="{% static 'images/example.jpg' %}" alt="Example Image">

{% static ‘images/example.jpg’ %}는 static 디렉터리 내 images 폴더에 있는 이미지 파일 example.jpg에 대한 URL을 생성합니다.

{% load static %} 는 항상 필수

include나 exclude와 상관 없이 해당 template에서 작성해줘야 하는 겁니다.

예를 들어 , 아래와 같이 include 태그 위에 {% load static %} 를 명시해줘도 include에 포함된 head.html에서 static 파일을 사용하는데 {% load static %}은 사용하지 않으면 template에서 이를 인식하지 못합니다.

base.html

<html lang="ko">
{% load static %}
{% include 'head.html' %}
<body>
    <div class="navbar">
		<h3>안녕하세요, {{ user }}님</h3>
    </div>

    <div class="container">
        {% block content %}
        {% endblock content %}
    </div>

</body>
</html>
```

head.html

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>장고 테스트</title>
    <link rel="stylesheet" href="{% static 'css/style.css' %}">
</head>

위와 같이 코드를 작성하면 TemplateSyntaxError at /
Invalid block tag on line 5: ‘static’. Did you forget to register or load this tag? 와 같은 에러가 발생 할 수 있습니다.

에러를 고치기 위해서는 아래와 같이 static 파일을 쓰는 template 자체에 {% load static %}을 작성해줘야 합니다.

특정 app에 종속되지 않게 static 파일 관리

settings.py 수정

프로젝트에는 특정 앱에 연결되지 않은 정적 파일들이 있을 수도 있습니다.

앱 내에서 static/ 디렉터리를 사용하는 것 외에도 설정 파일에서 Django가 정적 파일을 찾는 디렉터리 목록(STATICFILES_DIRS)을 정의할 수 있습니다.

STATICFILES_DIRS = [
    BASE_DIR / "static",
]

django document에서 staticfiles_dir 관련 부분

app마다 종속적인 정적 파일 관리 VS global 단일 정적 파일 관리

Django에서 각 앱의 정적 디렉터리를 관리하는 것과 독립적인 단일 정적 디렉터리를 관리하는 것에는 고유한 장단점이 있습니다.

각 앱에서 정적 디렉터리로 관리하는 경우

각 앱은 자체 정적 파일을 관리하므로 특정 앱 기능과 관련된 자산을 더 쉽게 구성하고 유지 관리할 수 있습니다.

또한 특정 앱을 작업하는 개발자는 해당 앱과 관련된 정적 파일 관리에만 집중하여 충돌이나 혼란의 위험을 줄일 수 있습니다.

다만 단점으로는
정적 파일은 여러 앱에 중복될 수 있으며 이로 인해 중복성이 발생하고 디스크 공간 사용량이 늘어날 수 있습니다

두 개의 앱에 동일한 이름이나 경로의 정적 파일이 포함되어 있는 경우 충돌이 발생하여 예기치 않은 동작이 발생하거나 디버깅이 어려울 수 있습니다.

글로벌 단일 정적 디렉토리로 관리하는 경우

모든 정적 파일이 하나의 디렉터리에 중앙 집중화되므로 전체 프로젝트의 자산을 더 쉽게 관리하고 유지할 수 있습니다.

또한 정적 파일은 한 번만 저장되므로 중복성이 줄어들고 디스크 공간이 절약됩니다.

배포 과정에서도 제공할 디렉터리가 하나뿐이므로 정적 파일 배포가 더 간단해집니다

하지만 단점으로는

정적 파일의 범위가 개별 앱에 국한되지 않기 때문에 다양한 앱 기능 간의 문제를 명확하게 구분하는 것이 더 어려울 수 있습니다.

단일 정적 디렉터리를 사용하면 다양한 앱 기능을 작업하는 개발자 간의 공동작업을 위해 충돌이나 중복을 피하기 위해 조정이 필요할 수 있습니다.

결론

궁극적으로 각 앱의 정적 디렉터리를 관리하는 것과 독립적인 단일 정적 디렉터리를 관리하는 것 사이의 결정은 프로젝트 규모, 팀 구조, 개발 선호도와 같은 요소에 따라 달라진다고 합니다.

그러나 대부분의 경우 하이브리드 접근 방식을 사용한다고 하네요.

저 역시 하이브리드 접근 방식이 가장 좋은 것 같습니다.

공통적으로 쓰이는 합의된 UI 요소들은 전역 디렉토리에, 각 app에 사용되는 고유의 정적 파일들은 각 app의 static 디렉토리에 사용하는 방식으로 진행해야 전체적인 UI는 유지하면서 각 app에서의 정적 파일 업데이트 및 관리도 수월해질 것 같습니다.

마치며

프레임워크라는 게 복잡한 과제에 대한 체계적인 방법을 제공해주다 보니 첫 진입장벽이 쉽지만은 않은 것 같습니다.

정적 파일을 관리하는 것 조차 초보 단계에서는 “왜 이렇게까지 복잡한 체계가 있는거지” 싶기도 합니다.

하지만 어차피 프로젝트의 크기가 커지게 되고 하면 겪게 되는 문제들에 대한 솔루션을 제공해주는 것이니 미리 프레임워크의 여러가지 체계과 방법들에 대해 공부하는 게 좋다고 생각이 듭니다.

참고하면 좋은 글

https://docs.djangoproject.com/en/5.0/howto/static-files/

Leave a Comment

목차