🖱 우선 접속
우선, 서버를 켜주고 admin 페이지에 접속해본다.
$ python manage.py runserver
# http://127.0.0.1:8000/admin/로 접속
로그인 후 위와 같은 화면이 나온다면 성공이다.
왼쪽의 사이드바를 보면 기본적으로 wagtail이 제공해주는 기능들이 들어가있다. 오늘은 첫 화면과 사이드바를 커스터마이징 해보겠다. 기본적으로는 django의 상속 매커니즘을 따른다.
✨ 첫 화면 커스터마이징
우선, wagtail의 admin 페이지에서는 모든 페이지를 하나의 app으로 취급한다. 따라서 app을 하나 만들고 [프로젝트명]/settings/base.py
로 들어가 그 app을 추가해준다. 만약 우선 만들어진 app 내에서 dashboard를 등록하고 싶다면 해당 app내의 templates/wagtailadmin/
폴더를 만들어주면 된다. 이번에는 난 따로 app을 만들었다.
$ python manage.py startapp dashboard
# [프로젝트명]/settings/base.py
INSTALLED_APPS = [
# ...
'dashboard',
'wagtail',
'wagtail.admin',
# ...
]
이제 준비는 끝났다. 그 다음, 아래와 같은 것들을 커스텀 할 수 있다.
1. 브랜딩 로고 변경
2. favicon 변경
3. admin 페이지 타이틀 변경
4. 로그인 페이지 변경
5. admin 페이지의 웰컴 메세지 변경
이것들은 전부 wagtailadmin이라는 app을 상속받아 커스텀 하는 것이다.
dashboard/templates/wagtailadmin/base.html
파일을 만들고 아래와 같이 코드를 입력하고, dashboard/static/images
폴더 안에 원하는 이미지 파일을 저장한다.
<!-- 기본적으론 wagtailadmin app안의 base.html을 상속받아 사용한다 -->
{% extends "wagtailadmin/base.html" %}
{% load static %}
{% block branding_logo %}
<img src="{% static 'images/[이미지 파일명]' %}" alt="Custom Project" width="80" />
{% endblock %}
이렇게 변경한 로고는 login 페이지, 404 페이지, wagtail userbar에 상속시킨다.
dashboard/templates/wagtailadmin/admin_base.html
파일을 만들고 아래와 같이 코드를 입력한다. 편의상 나는 로고와 같은 이미지 파일로 넣었다.
{% extends "wagtailadmin/admin_base.html" %}
{% load static %}
{% block branding_favicon %}
<link rel="shortcut icon" href="{% static 'images/[이미지 파일명]' %}" />
{% endblock %}
favicon을 변경할 때와 같은 html 파일(dashboard/templates/wagtailadmin/admin_base.html
)에 아래와 같이 코드를 추가한다.
{% block branding_title %}[넣고 싶은 문구]{% endblock %}
dashboard/templates/wagtailadmin/login.html
파일을 만들고 아래와 같이 코드를 입력한다.
{% extends "wagtailadmin/login.html" %}
{% block branding_login %}[넣고 싶은 문구2]{% endblock %}
dashboard/templates/wagtailadmin/home.html
파일을 만들고 아래와 같이 코드를 입력한다.
{% extends "wagtailadmin/home.html" %}
{% block branding_welcome %}[넣고 싶은 문구3]{% endblock %}
무사히 커스텀이 된 것을 볼 수 있다. 만약 css를 수정하고 싶다면 dashboard/static/css
폴더를 만들어 css 파일을 작성한 뒤, 적용시키고 싶은 html 코드에 {% load static %}
만 추가해주면 된다.
🎡 사이드바 커스텀 + 기능 구현
이제 본격적으로 기능들을 구현하기로 하자. 우선, 다시 한 번 구현해야 하는 기능들을 되짚어보면
이며, 나는 1번 기능을 upload라는 app, 2번 기능을 crawl이라는 app, 3번과 4번 기능을 retrieve라는 app으로 구현할 것이다.
우선, app을 생성해주고 [프로젝트명]/settings/base.py
에 app을 등록한다.
$ python manage.py startapp upload
$ python manage.py startapp crawl
$ python manage.py startapp retrieve
# [프로젝트명]/settings/base.py
INSTALLED_APPS = [
# ...
'dashboard',
"upload",
"crawl",
"retrieve"
# ...
]
또 다시 준비가 끝났다. 이 다음, 우리는 admin 페이지의 사이드바에 해당 앱들을 등록해주어야 한다. 그 전에 이해해야 하는 개념이 있다. 바로 hook이다.
로드 시 Wagtail은 wagtail_hooks.py 파일이 있는 앱을 검색하여 내용을 실행합니다. 페이지를 저장하거나 메인 메뉴를 구성하는 등 Wagtail 실행의 특정 시점에서 실행할 수 있는 자체 기능을 등록하는 방법을 제공합니다.
라는 wagtail 공식문서의 설명이다. 간단하게 말하면 app들 중에 wagtail_hooks.py
파일이 있으면 사용자 정의 기능을 추가하고 wagtail에게 인식시킬 수 있다는 뜻이다.
이를 위해선 wagtail_hooks.py
라는 파일을 app 안에 만들어야 한다. 원하는 app아래에 views.py
랑 같은 레벨에 wagtail_hooks.py
파일을 생성한 뒤 아래와 같이 코드를 작성한다.
from django.urls import path, reverse
from wagtail import hooks
from wagtail.admin.menu import MenuItem
from .views import index
@hooks.register('register_admin_urls')
def register_upload_url():
return [
path('upload/', index, name='upload')
]
@hooks.register('register_admin_menu_item')
def register_upload_menu_item():
return MenuItem('Upload', reverse('upload'), icon_name='upload')
저 @hooks.register
데코레이션을 통해 admin 페이지에게 '여기도 app 있어요~~'라고 알려준다고 생각하면 된다. @hooks.register('register_admin_urls')
을 통해 url을 추가해주고, @hooks.register('register_admin_menu_item')
을 통해 사이드바 메뉴에 추가해준다.
그리고, MenuItem을 리턴할 때 url도 같이 전달해야 하는데, 그 때 사용하는게 바로 reverse이다. reverse는 Django에서 url을 역으로 검색할 떄 사용하는 함수로, url의 이름을 기반으로 url을 찾아내는 것이다. 즉, register_upload_url
함수를 통해 만들어낸 url을 name기반으로 다시 찾아내서 그 값을 리턴한다고 생각하면 된다.
그리고, icon_name으로 귀염뽀짝한 아이콘들도 커스텀 가능하다.
그 다음, upload 폴더 안에 templates/upload/index.html
파일을 만들어 준다.
{% extends "wagtailadmin/base.html" %}
{% block content %}
{% include "wagtailadmin/shared/header.html" %} {% load static %}
<div class="nice-padding">
<h2>파일 업로드</h2>
<form method="post" enctype="multipart/form-data">
{% csrf_token %}
<input type="file" name="upload" accept="">
<button class="button button-secondary" type="submit">Submit</button>
</form>
{% endblock %}
{% extends "wagtailadmin/base.html" %}
로 기본 틀을 상속받고 {% block content %}
안에 원하는 요소들을 넣어주고, {% include "wagtailadmin/shared/header.html" %}
에서 header를 상속받아 요소들을 보기 좋은 위치에 놓고, {% load static %}
로 css와 js를 가져온다. 이 때, 주의할 점이 있다.
<form>
태그에서 enctype은 본인의 서비스 목적에 맞게 설정해야 한다. 나는 주로 json파일이나 텍스트 파일 등을 업로드 할 것이기 때문에 form-data를 사용했지만, 그 외의 경우도 있을 수 있기 때문에 꼭 확인하고 설정해준다.<input>
태그에서 accept인자도 본인의 서비스 목적에 맞게 설정해야 한다. 이것도 똑같이 확인 후 설정한다. [프로젝트명]/settings/base.py
의 INSTALLED_APPS
에 "wagtail.contrib.styleguide"를 추가해준다. 그 뒤에, admin 페이지의 사이바에서 Settings를 누른 뒤 맨 밑을 보면 styleguide 버튼이 추가된 것을 볼 수 있다. 거기서 원하는 요소의 class나 id 이름을 가져다 쓰면 된다. 그 다음, views.py
파일에 가서 아래와 같이 코드를 작성한다.
from django.shortcuts import render
from django.core.files.storage import FileSystemStorage
import time
def index(request) :
if request.method == 'POST' and request.FILES['upload']:
start = time.time()
upload = request.FILES['upload']
fss = FileSystemStorage()
file = fss.save(upload.name, upload)
file_url = fss.url(file)
end = time.time()
total_time = end-start
return render(request, 'upload/index.html', {'file_url': file_url, 'total_time':total_time})
return render(request, 'upload/index.html')
간단하게 보자면, request.method가 POST이고, 전달받은 파일이 있을 때, upload라는 파일로 전달받아 fss.save
를 통해 파일의 이름과 내용물을 전달한다. 그리고 걸린 시간과 파일이 저장된 url을 화면에 전달한다. 다시 한 번 index.html
파일에 가서 아래 코드와 같이 작성한다.
{% extends "wagtailadmin/base.html" %}
{% block content %}
{% include "wagtailadmin/shared/header.html" %} {% load static %}
<div class="nice-padding">
<h1 class="w-header__title" id="header-title">파일 업로드</h1>
<form method="post" enctype="multipart/form-data">
{% csrf_token %}
<input type="file" name="upload" accept="">
<button class="button button-secondary" type="submit">Submit</button>
</form>
<!--추가된 부분-->
{% if file_url %}
<p>파일이 저장된 url : {{ file_url }}</p>
<p>총 {{ total_time }}초가 걸림</p>
{% endif %}
<!--추가된 부분-->
{% endblock %}
여기까지 하면, 아래와 같은 화면을 만날 수 있다. 나는 ㄴ.txt라는 파일을 임시로 넣어봤고, submit을 누르면 django 프로젝트 아래에 media
라는 폴더가 새로 생성된 것을 알 수 있고, 거기에 파일이 들어가있을 것이다.
media가 저장되는 위치는 settings/base.py
에서 수정 가능하다.
MEDIA_ROOT = os.path.join(BASE_DIR, "media")
MEDIA_URL = "/media/"
🎃 비슷하게 쫘좌작
해나가면 된다. 다음은 크롤링 하는 페이지와 데이터를 조회하는 페이지를 구현해보겠다.