https://www.youtube.com/watch?v=RQ0eKv6HrpM 

https://wagtail.org/blog/wagtail-heroku-2017/

 

먼저 위에 사이트에서 운영체제에 맞는 Heroku를 다운 받도록 하자.

 

 

1. Heroku 설치

https://devcenter.heroku.com/articles/heroku-cli

 

The Heroku CLI | Heroku Dev Center

Last updated February 01, 2022 The Heroku Command Line Interface (CLI) lets you create and manage Heroku apps directly from the terminal. It’s an essential part of using Heroku. Install the Heroku CLI Pre-requisites The Heroku CLI requires Git, the popul

devcenter.heroku.com

먼저 위에 사이트에서 운영체제에 맞는 Heroku를 다운 받도록 하자.

 

 

2. Django-toolbelt 설치

배포를 위한 관련 라이브러리를 모아놓은 라이브러리이다. 

 

  • django
  • psycopg2
  • gunicorn
  • dj-database-url
  • dj-static

위에 라이브러리들이 설치된다.

 

pip freeze > requirements.txt

requirements.txt파일을 업데이트 해준다.

 

 

3. 데이터 베이스 설정 (PostreSQL)

https://vicapor.tistory.com/142

https://vicapor.tistory.com/122

 

참고

 

 

4. Procfile 생성

 

Procfile

web: gunicorn 프로젝트이름.wsgi --log-file -

 

 

5. runtime.txt 파일 생성

https://devcenter.heroku.com/articles/python-support

 

위의 사이트에서 지원되는 파이썬 버전을 확인해 볼 수 있다.

 

python-3.8.12

나는 프로젝트에서 사용한 3.8.12버전으로 진행해보겠다.

 

 

6. settings/production.py 수정

# Parse database configuration from $DATABASE_URL
import dj_database_url
DATABASES['default'] =  dj_database_url.config()
	
# Honor the 'X-Forwarded-Proto' header for request.is_secure()
SECURE_PROXY_SSL_HEADER = ('HTTP_X_FORWARDED_PROTO', 'https')

# Allow all host headers
ALLOWED_HOSTS = ['*']

아직 Heroku url을 모르기 때문에 ALLOWED_HOSTS는 모두 허용을 해놓는다.

 

 

7. .gitIgnore 파일 생성

*.pyc
.DS_Store
*.swp
/venv/
/static/
/media/
.env

이미 git에 연결했으면 .gitignore파일이 존재할 것이다. 위의 내용을 추가해주자.

 

 

8. .env 파일생성

 

.env

DJANGO_SETTINGS_MODULE=project_title.settings.production
SECRET_KEY='####'

 

 

9. Production.py 파일 수정

from __future__ import absolute_import, unicode_literals
from .base import *
import dj_database_url
import os

env = os.environ.copy()
SECRET_KEY = env['SECRET_KEY']

중요한 것은 __future__은 제일 먼저 import 되어야 하므로 맨 위에 적는다.

 

 

10. Heroku 배포

 

배포전에 git에 push를 해놓자!!

 

git init
git add .
git commit -m "first commit to heroku"
heroku create 
# Creates a new Heroku app and connects it to your initialised git repo
git push heroku master 
# Pushes your commited code up to your new ap
heroku plugins:install heroku-config
# Install plugin that allows us to push settings to heroku
heroku config:push
# Pushes settings to heroku, if you get an error check your spaces.
heroku run python manage.py migrate 
# Heroku allows you to run shell commands remotely with the 'heroku run' command.
heroku run python manage.py createsuperuser
# Creates a new superuser on Heroku
heroku ps:scale web=1 
# Ensures that a new Dyno is running for your project

 

issue) 

Dependency on app with no migrations: user 오류가 발생했다. 

user app의 migrations폴더에 0001_initial.py을 .gitignore에 포함시키고 git push를 해주면 된다. 

user app에 user model이 정의 되어 있는데 diary app에서 user를 사용하기 때문에 dependency오류가 발생하는 것 같다.

 

 

11. whitenoise제거

 

pip install whitenoise

 

MIDDLEWARE = [

	...
    'whitenoise.middleware.WhiteNoiseMiddleware',

]

 

 

settings/production.py

STATICFILES_STORAGE = 'whitenoise.storage.CompressedManifestStaticFilesStorage'

COMPRESS_OFFLINE = True
COMPRESS_CSS_FILTERS = [
    'compressor.filters.css_default.CssAbsoluteFilter',
    'compressor.filters.cssmin.CSSMinFilter',
]
COMPRESS_CSS_HASHING_METHOD = 'content'

 

git push heroku master

 

 

heroku에 대한 자세한 설명이 보고싶다면

heroku help

 

추가) 

Heroku에서는 Local에서 makemigrations를 진행하고 migrations 파일까지 전부 git에 업로드 해야한다. 그리고 heroku에서 migrate를 해줘야한다. 

'Back-End > Wagtail, Django 배포' 카테고리의 다른 글

DumpData  (0) 2022.01.08
Wagtail RichText API  (0) 2022.01.07
2. Gunicorn, Nginx 적용  (0) 2021.12.23
1. PostgreSQL 적용  (0) 2021.12.22
3. Docker(Django, Wagtail)  (0) 2021.12.22

ModelAdmin에서 검색을 하는 방법이 있다. 

Django 에서는 기본적으로 DjangoORMSearchHandler 을 제공한다.  https://docs.djangoproject.com/en/4.0/ref/contrib/admin/#django.contrib.admin.ModelAdmin.search_fields

 

The Django admin site | Django documentation | Django

Django The web framework for perfectionists with deadlines. Overview Download Documentation News Community Code Issues About ♥ Donate

docs.djangoproject.com

모델의 CharField, TextField, RichTextField or StreamField만 검색을 제공하고 foreignkey의 속성을 검색하고 싶으면 

foreignkey__atrribute로 검색하면 된다. 그리고 wagtail에서는 ','을 붙여줘야한다. 

class UserCourseAdmin(ModelAdmin):
    model = UserCourse
    menu_label = '사용자 신청 강의 관리'  # ditch this to use verbose_name_plural from model
    menu_icon = 'list-ol'  # change as required
    list_display = ('user_email', 'course',)
    search_fields = ['user__email',]
    #search_handler_class = WagtailBackendSearchHandler

list_display에는 @property를 사용할 수 있으므로 저렇게 추가적인 외래키의 내용이 필요하다면 정의해주자.

 

 

 

 

Wagtail에서는 WagtailBackendSearchHandler를 제공하는데 문제는 모델의 필드들만 검색이 가능하다. 

search_handler_class = WagtailBackendSearchHandler

https://docs.wagtail.io/en/stable/reference/contrib/modeladmin/indexview.html#modeladmin-search-fields

'Back-End > Wagtail, Django' 카테고리의 다른 글

Wagtail 프로젝트 배포  (0) 2021.12.20
Wagtail Changing the Admin Display Title  (0) 2021.12.03
Wagtail Routable  (0) 2021.12.03
Wagtail StreamField Options  (0) 2021.12.02
Wagtail Custom Page Properties  (0) 2021.12.02

https://www.accordbox.com/blog/how-export-restore-wagtail-site/

 

# postgres
python -Xutf8 manage.py dumpdata --natural-foreign --indent 2 \
    -e contenttypes -e auth.permission -e postgres_search.indexentry \
    -e wagtailcore.groupcollectionpermission \
    -e wagtailcore.grouppagepermission -e wagtailimages.rendition \
    -e sessions > data.json
    
# sqlite
python -Xutf8 manage.py dumpdata --natural-foreign --indent 2 -e contenttypes -e auth.permission -e wagtailsearch.indexentry -e wagtailcore.groupcollectionpermission -e wagtailcore.grouppagepermission -e wagtailimages.rendition -e sessions -e wagtailcore.pagerevision > data.json

python -Xutf8 manage.py dumpdata --indent 2 > data.json

 

import os

from django.conf import settings
from django.core.files.storage import default_storage, FileSystemStorage
from django.core.management.base import BaseCommand
from django.core.management import call_command

from wagtail.core.models import Site, Page


class Command(BaseCommand):
    def _copy_files(self, local_storage, path):
        """
        Recursively copy files from local_storage to default_storage. Used
        to automatically bootstrap the media directory (both locally and on
        cloud providers) with the images linked from the initial data (and
        included in MEDIA_ROOT).
        """
        directories, file_names = local_storage.listdir(path)
        for directory in directories:
            self._copy_files(local_storage, path + directory + '/')
        for file_name in file_names:
            with local_storage.open(path + file_name) as file_:
                default_storage.save(path + file_name, file_)

    def handle(self, **options):
        fixtures_dir = os.path.join(settings.PROJECT_DIR, 'fixtures')
        print(os.path.join(fixtures_dir, 'ezstbackend.json'))
        fixture_file = os.path.join(fixtures_dir, 'ezstbackend.json')

        print("Copying media files to configured storage...")
        local_storage = FileSystemStorage(os.path.join(fixtures_dir, 'media'))
        self._copy_files(local_storage, '')  # file storage paths are relative

        # Wagtail creates default Site and Page instances during install, but we already have
        # them in the data load. Remove the auto-generated ones.
        if Site.objects.filter(hostname='localhost').exists():
            Site.objects.get(hostname='localhost').delete()
        if Page.objects.filter(title='Welcome to your new Wagtail site!').exists():
            Page.objects.get(title='Welcome to your new Wagtail site!').delete()

        call_command('loaddata', fixture_file, verbosity=0)

        print("Awesome. Your data is loaded! The bakery's doors are almost ready to open...")

 

python manage.py load_initial_data

python manage.py loaddata data.json

'Back-End > Wagtail, Django 배포' 카테고리의 다른 글

Wagtail Heroku Deploy  (0) 2022.03.01
Wagtail RichText API  (0) 2022.01.07
2. Gunicorn, Nginx 적용  (0) 2021.12.23
1. PostgreSQL 적용  (0) 2021.12.22
3. Docker(Django, Wagtail)  (0) 2021.12.22

**참고 사이트**
https://docs.wagtail.io/en/stable/extending/rich_text_internals.html#rich-text-internals
https://github.com/wagtail/wagtail/issues/2695

**Issue**
RichEditor에서 Image나 file을 사용할 때 Wagtail 자체에서 embed tag로 변환해서 Database에 저장합니다. 

 

<embed embedtype="image" id="10" alt="A pied wagtail" format="left" />


Wagtail Template에서 |richtext가 바로 위 embed태그를 parse해주는 Template태그입니다. 다만 Api 전달할 때에는 그대로 embed 태그로 오기 때문에 이를 변환해서 Api에 사용할 수 있는 방법이 필요합니다. (이는 FrontEnd에서 v-html로 바로 변환해서 사용 해야 하기 때문에 그렇습니다.)

**해결**
그래서 전달되는 RichText의 Image를 원하는 형식에 맞게 바꾸고 이를 변환해서 API에 전달하는 방식에 대해서 고민하고 property를 사용해서 해결했습니다. 

 

handlers.py

from wagtail.core.rich_text import EmbedHandler
from wagtail.images.models import Image


class ImageHandler(EmbedHandler):
    identifier = 'image'

    @classmethod
    def expand_db_attributes(cls, attrs):
        image = Image.objects.get(pk=attrs['id'])
        image_url = image.file.name
        image_endpoint = "http://127.0.0.1:8000/media/" + image_url
        response_format = '<img class="richtext-%s" src="%s" alt="%s" />'
        return response_format % (
            attrs['format'],
            image_endpoint,
            attrs['alt'])

 

 

wagtail_hooks.py

from .handlers import ImageHandler

@hooks.register("register_rich_text_features", order=10)
def register_embed_handler(features):
    features.register_embed_type(ImageHandler)

 

 

models.py

from wagtail.core.rich_text import expand_db_html

@property
  def intro_api(self):
  	return expand_db_html(self.intro)

 

 

schema.py

intro_api: str

 

 

되는 코드인데 안된다고 생각되었을 경우 다른 곳에서 원인을 찾아보자!!

'Back-End > Wagtail, Django 배포' 카테고리의 다른 글

Wagtail Heroku Deploy  (0) 2022.03.01
DumpData  (0) 2022.01.08
2. Gunicorn, Nginx 적용  (0) 2021.12.23
1. PostgreSQL 적용  (0) 2021.12.22
3. Docker(Django, Wagtail)  (0) 2021.12.22

Gunicorn, Nginx? 

지금까지는 python manage.py runserver 명령을 사용해서 서버를 실행시켰다. 하지만 실제로 서버에서 웹사이트를 운영할 때 방문자가 많아지면 성능, 보안 등의 문제가 발생할 수 있다. 이런 상황에 대응하기 위해 전문적인 웹 서버 소프트웨어를 사용해 서버를 실행시켜야한다. 웹 서버 소프트웨어를 사용하면 방문자의 요청에 더 빠르게 응답할 수 있고, 많은 사용자가 동시에 접속했을 때 여러 대의 서버로 요청을 분산하는 로드 밸런싱 같은 기능도 제공.

 

 

Django에서 웹 서버 소프트웨어는 보통 Nginx를 사용한다. 웹 서버 소프트웨어와 Django를 연결하기 위해 WSGI(Web Server Gateway Interface)인 Gunicorn을 사용한다. 

 

 

1. Gunicorn 적용 

 

 

1) 설치

pip install gunicorn

 

 

2) settings.py 수정

STATIC_ROOT = os.path.join(BASE_DIR, 'static')
STATIC_URL = '/static/'

MEDIA_ROOT = os.path.join(BASE_DIR, 'media')
MEDIA_URL = '/media/'

 

 

3) urls.py 수정

urlpatterns += static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
urlpatterns += static(settings.STATIC_URL, document_root=settings.STATIC_ROOT)

 

 

2. Nginx 적용

 

Nginx 적용이라기보단 Docker에서 Nginx 적용을 위한 설정 파일의 생성이다.

 

 

nginx/nginx.conf

upstream do_it_django {
    server web:8000;
}

server {
    listen 80;
    server_name something.com; # 서버 이름 설정

    location / {
        return 301 https://$host$request_uri;
    }

    location /.well-known/acme-challenge/ {
        root /var/www/certbot;
    }
}

server {
    listen 443 ssl;
    server_name something.com; # 서버 이름 설정

    location / {
        proxy_pass http://something; # 서버 domain (.com 제외)
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header Host $host;
        proxy_redirect off;
    }

    location /static/ {
        alias /usr/src/app/_static/;
    }

    location /media/ {
        alias /usr/src/app/_media/;
    }

    ssl_certificate /etc/letsencrypt/live/서버 도메인(something.com)/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/서버 도메인(something.com)/privkey.pem; # 서버 접속 .pem 키
    include /etc/letsencrypt/options-ssl-nginx.conf;
    ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem;

}

 

 

 

'Back-End > Wagtail, Django 배포' 카테고리의 다른 글

DumpData  (0) 2022.01.08
Wagtail RichText API  (0) 2022.01.07
1. PostgreSQL 적용  (0) 2021.12.22
3. Docker(Django, Wagtail)  (0) 2021.12.22
4. AWS (인스턴스 생성, 서버 접속)  (0) 2021.12.20

PostgreSQL이란?

PostgreSQL은 확장 가능성 및 표준 준수를 강조하는 객체-관계형 데이터베이스 관리 시스템(ORDBMS)의 하나이다. BSD 허가권으로 배포되며 오픈소스 개발자 및 관련 회사들이 개발에 참여하고 있다.

 

Django나 Wagtail에서는 기본적으로 Sqlite3를 제공하고 있다. 그러나 충분한 성능을 기대하긴 어렵다. 그래서 오픈 소스로 사용가능한 PostgreSQL을 적용해보자. 

 

 

 

-윈도우는 아래 링크 참고-

https://dora-guide.com/postgresql-install/

https://m.blog.naver.com/ilsan_ilsan/221493158294

 

 

1. PostgreSQL 설치

pip install psycopg2-binary

 

 

2. Settings

 

 

settings.py

DATABASES = {
    'default': {
        'ENGINE': os.environ.get('SQL_ENGINE', 'django.db.backends.sqlite3'),
        'NAME': os.environ.get('SQL_DATABASE', os.path.join(BASE_DIR, 'db.sqlite3')),
        'USER': os.environ.get('SQL_USER', 'user'),
        'PASSWORD': os.environ.get('SQL_PASSWORD', 'password'),
        'HOST': os.environ.get('SQL_HOST', 'localhost'),
        'PORT': os.environ.get('SQL_PORT', '5432'),
    }
}

os.environ.get은 배포를 위해 만들어 놓은 .env 파일에서 설정을 가져와서 사용한다는 것이다.

로컬에서는 sqlite3를 계속해서 사용하기 위해 뒤에 입력해준다. 

 

 

추가)

 

.env 파일이란?

 

환경변수 설정 파일이다. 기존에 local에서 개발할 때 처럼 settings.py에 데이터베이스 정보, Django Secret Key등을 입력하게 되면 보안 문제를 야기할 수 있다. 그래서 .env 파일을 만들고 .gitignore에 추가시켜 업로드 되지 않게 관리하는 것이 바람직하다. 

 

 

.env

DEBUG=True
SECRET_KEY=django-insecure-ivndf...
DJANGO_ALLOWED_HOSTS=localhost 127.0.0.1 [::1]

SQL_ENGINE=django.db.backends.postgresql_psycopg2
SQL_DATABASE=wagtail
SQL_USER=vicapor
SQL_PASSWORD=1234
SQL_HOST=db
SQL_PORT=5432
DATABASE=postgres

.env 파일의 예시이다. 

 

 

.gitignore

...

# .env 파일 push 방지
.env.prod
.env.db
.env.dev

위와 같이 생성한 .env 파일을 gitignore 해주면 된다.

 

 

Django SecretKey 재생성

 

Django Secretkey는 중요한 역할을 한다. 예를 들어 클라이언트에서 request로 token 값이 왔을 때, Django SecretKey와 암호화 알고리즘을 사용하여 암호화 한다. 만약 노출 되었을 경우 변경은 필수적이다. 

 

 

# python shell 접속
python manage.py shell


# shell에서 실행
from django.core.management.utils import get_random_secret_key

get_random_secret_key()

 

'Back-End > Wagtail, Django 배포' 카테고리의 다른 글

DumpData  (0) 2022.01.08
Wagtail RichText API  (0) 2022.01.07
2. Gunicorn, Nginx 적용  (0) 2021.12.23
3. Docker(Django, Wagtail)  (0) 2021.12.22
4. AWS (인스턴스 생성, 서버 접속)  (0) 2021.12.20

+ Recent posts