IT/컴퓨터 (26개의 글)

Django 프레임워크로 RSS 피드 만들기 

2020. 02. 23 IT/컴퓨터 > Django
블로그를 네이버 등 검색엔진에 등록하려면 RSS 피드를 제출하는 것이 좋다고 한다. 사실 예전부터 RSS라는 말은 많이 들어 봤지만 실제로 사용해본 적이 없고, 주변에서 RSS를 통해 구독하는 사람도 본 적이 없어서 어떤 것인지 개념이 모호한 상태였다. 새로 RSS 피드를 만들면서 간단히 공부해 보았다.   RSS는 Really Simple Syndication, 혹은 Rich Site Summary 의 약자라고 하는데, syndication은 또 뭔가? 전통적인 사전적 의미는 기사, 사진, 텔레비전 프로그램 등을 여러 신문사 등에 파는 행위를 syndication이라고 하는 것 같다. 요즘 주로 쓰이는 의미는 블로그등 웹사이트의 컨텐츠를 타겟 구독층에 노출시키는 것을 말한다.   Really Simple Syndication, 즉 자기 글을 아주 간단하게 사람들한테 배포할 수 있는 기술이라는건데..실제로 구동되는 방식은, 사이트에서 RSS 피드를 제공하면 경우 방문자가 관심있는 피드 주소들을 RSS 리더 등의 프로그램을 이용해서 등록해 둔다. 그러면 사이트에 새 글이 올라오는 경우 그 사이트들을 일일이 돌아다니지 않아도 RSS 리더 프로그램이 자동으로 새 글이 떴다는 것을 알려주게 된다. 그렇게 해서 구독자는 쉽게 여러 관심 사이트에 올라오는 새로운 컨텐츠를 확인할 수 있고, 반대로 매체 입장에서도 컨텐츠를 쉽게 사람들에게 전달하는 채널이 되는 것이다. 두번째 약자인 Rich Site Summary 라는 표현은 좀 더 기술적이고 직설적인 표현인데, 개념은 이전에 기술한 사이트맵 (sitemap.xml) 과 비슷한것같다. 사이트의 컨텐츠 내용을 요약해서 보여 주는 페이지라는 얘기다. 참고: Django sitemap 프레임워크를 이용해서 사이트맵 만들기 차이점은, 사이트맵은 간단히 제목과 링크 정도만 제공하는 대신 사이트 전체의 컨텐츠를 모두 요약해서 보여주는 것이 목적인 반면 RSS 피드는 전체 컨텐츠를 다 전달하는 것이 아니라 주로 최근에 발행된 컨텐츠를 모아서 전달해주는 것이라는 점이다. RSS 의 목적상 방문자가 사이트에 직접 들어오지 않아도 내용을 알 수 있어야 하므로 사이트맵처럼 제목 위주의 간단한 요약이 아니라, 글 본문과 첨부된 사진같은 해당 컨텐츠의 내용 전체를 제공해 주는것이 권장된다고 한다 (즉 풍부한 사이트 요약 = Rich Site Summary).   장고(Django) 프레임워크에는 간단하게 RSS 피드를 생성할 수 있는 syndication feed framework 라는 도구가 포함되어 있다. 이를 이용하면 RSS 와 Atom 피드를 쉽게 생성할 수 있다.   #1. 우선 models.py 에 다음과 같이 블로그 글을 정의하는 Post라는 모델이 이미 구성되어 있다. (설명을 간략하게 하기 위해 기타 field 는 생략함)   #2. 이후 feeds.py 라는 파일을 새로 만들어 생성될 RSS feed 의 내용을 정의해 준다. 파일의 위치는 어디이든 상관 없지만, 가급적이면 models.py 와 같은 디렉토리에 만들어주는 것이 관리에 편할 것 같다.   우선 Feed 클래스를 import 해 주고 그 클래스를 상속해 원하는 내용을 담을 feed 클래스를 정의해 주면 된다. models.py 에서 Post 클래스를 import 해 주어야 내용을 읽어올 수 있다.  Feed 클래스에는 미리 정의된 속성이 있는데, 위에서 title, link, description 은 나중에 생성될 RSS feed의 <title>, <link>, <description> 에 보여지는 속성이므로 알맞게 작성하면 되겠다. 이후에 역시 Feed 클래스에 미리 정의된 메서드들을 정의하면 되는데, 우선 가장 기본적인 items() 에는 RSS에 표시할 글들을 Django Queryset 을 이용해서 읽어 오면 된다. 위의 코드는 이 블로그에 등록된 글 중 발행이 된 글만 찾아오도록 필터를 해 주고 그 중 최근 발행 일자 글 10개를 return 하도록 한 것인데, 필터가 필요 없는 경우에는 식으로 하면 될 것이다. Queryset 에서 데이터를 읽어오는 작업은 Django 작업을 하면서 가장 기본적인 내용 중 하나이니 관련된 내용을 나중에 정리해 보겠다. 이렇게 items()를 작성하고 나서, RSS feed에 표시해주고 싶은 내용들을 메서드를 이용해 정의해주면 된다. 위 코드의 item_title(), item_description(), item_link() 의 내용들이다. 참고로 이 메서드의 이름은 임의로 정한 것이 아니라 Feed 클래스 내에 이미 설정되어 있는 것들이다. item_link() 의 경우 해당 글로 바로 연결되는 URL 을 제공해주는 것이다.   #3. 그리고 나서 프로젝트 최상위의 urls.py 에 방금 작성한 feed를 연결할 수 있는 URL 을 매핑해준다. 이렇게 하면 주소창에 windybay.net/feeds/ 를 입력했을때 RSS 피드가 보이게 된다.   여기까지 진행하면 RSS 리더 등에서 feed를 읽어들이는데 문제는 없다. 그런데 다른 사이트들의 경우 RSS feed 링크를 클릭하면 태그에 따라 깔끔하게 정리된 XML 포맷으로 보여지는데, 위의 방법으로 만든 feed 는 지저분하게 일반 text 파일처럼 아무 정리가 안 된 파일이 보이는 것이 문제이다. 예를 들어 아래와 같은 식으로..   그리고 파이어폭스 등 브라우저에 따라서는 feed의 내용이 보이는 것이 아니라 해당되는 파일을 다운로드 하는 창이 바로 열리는 등 불편한 점이 있다. 이것은 Django 가 자동으로 만들어주는 feed 의 기본 타입이 application/rss+xml 이라는 타입이라서 발생하는 문제라고 한다. 컨텐츠의 타입을 application/xml 로 지정해 주면 이런 문제가 해결된다. Django 에서 feed의 타입을 지정해주기 위해 준비해놓은 Class가 여러가지 있는데, 여기서는 DefaultFeed 클래스를 이용해 문제를 해결하면 된다.    #4. 우선 위의 코드에 DefaultFeed를 임포트하는 문을 추가해주고, 이를 상속해서 content_type 을 지정해주는 클래스를 새로 만든다. 그리고 나서 만들어두었던 RecentPostsFeed 클래스 안에 'feed_type' 속성을 지정해주면 된다.   이렇게 하면 브라우저에서 feed의 내용을 읽어 잘 정리된 XML 포맷으로 보여주게 된다.     사실 RSS 피드를 이용해서 글을 구독해본 적이 없어서 관련된 내용을 잘 모르고 있었는데, 내용을 공부하면서 RSS 리더들을 이용해보니 잘 정리된 블로그들을 모아서 구독하는 데는 편리한 점이 있는것 같다. 피드를 작성해 두면 인터넷에 사이트를 노출시키는 데도 도움이 되니 가능하면 RSS 피드도 제공하는 것이 좋겠다.

Django sitemap 프레임워크를 이용해서 사이트맵 만들기 

2020. 02. 20 IT/컴퓨터 > Django
  블로그를 만들고 구글과 네이버 등에 등록을 하고 보니 사이트맵을 제출해야 한다고 한다. 사이트맵이라고 하면 사용자들이 사이트 구조를 파악하기 쉽도록 메뉴를 보기좋게 나열해 놓은 페이지만 생각했었는데, 알고보니 XML 파일로 검색엔진이 사이트 내의 링크 목록을 크롤링하기 쉽게 알려주는 작업이 필요한 것이었다.  사이트맵이 없더라도 검색엔진이 알아서 페이지들을 크롤링하고 링크를 수집할 수는 있지만, 사이트 구조가 복잡하거나 쉽게 노출되지 않는 페이지가 있는 경우에는 사이트 내의 콘텐츠가 검색 결과에 잘 노출되지 않기 때문에 미리 링크가 정리된 XML 사이트맵을 제공해 주는것이 좋다고 한다. 구글과 네이버 검색 등록시에 사이트맵이 제출되어 있으면 더 좋은 점수를 받는다. 웹에서 사이트 주소를 입력하면 XML 파일을 생성해주는 서비스를 하는 사이트들이 있어 그런 곳을 이용하면 쉽게 만들 수 있다고 한다. 하지만 Django로 작업을 한 경우에는 Django 내에 사이트맵을 생성해주는 프레임워크가 내장되어 있어 이것을 이용하면 사이트의 내용이 추가될 때마다 자동으로 업데이트되는 XML 사이트맵을 쉽게 만들 수 있다. 이 포스트에서는 Django를 이용해 사이트맵을 만드는 방법을 정리해 본다. Django 공식 documentation 내용을 주로 참고했다. #1. Sitemap 프레임워크는 sites 프레임워크가 활성화 되어 있어야 동작한다. 우선 프로젝트의 settings.py 파일의 INSTALLED_APPS 목록에 'django.contrib.sites'와django.contrib.sitemaps'   를 추가해 주고 settings.py 안의 적당한 곳에 'SITE_ID = 1' 이라고 지정해 준다.   #2. settings.py 안의 TEMPLATES 설정에서 다음 두 가지 설정이 되어있는지 확인한다. Django 프로젝트를 생성할때 디폴트로 생성되므로 바꾼 적이 없다면 그대로 두면 된다.   #3. 사이트맵의 url 을 설정해 주어야 한다. 프로젝트의 가장 상위의 urls.py 에 다음을 추가해 준다.   이제 도메인/sitemap.xml 에 접근하면 Django 가 동적으로 sitemap 을 생성해 준다. Django 는 sitemap.xml 의 위치를 기준으로 현재 위치와 그보다 하위의 URL 만 포함시키므로, 특별한 이유가 없다면 프로젝트의 root 디렉토리에 sitemap.xml 을 생성해주는것이 좋다.   #4. 사이트맵은 django.contrib.sitemaps 패키지의 Sitemap 클래스를 이용해서 생성한다.  사이트맵의 내용을 담은 sitemaps.py 파일을 따로 작성해 주면 편하다. 우선 블로그의 Post 모델을 불러와서 모든 publish 된 포스트에 대한 링크를 포함하고 있는 사이트맵을 만들어 본다. sitemaps.py 에 새로운 클래스를 생성하고, urls.py 에서 해당 클래스를 포함한 딕셔너리를 #3.에서 지정한  'sitemap.xml' 에 전달해준다.     XML 사이트맵은 URL 정보를 표시하기 위해 기본적으로 <loc> 태그를 반드시 포함해야 하고, 추가로 <lastmod>, <changefreq>, <priority> 태그를 이용해 부가 정보를 표시해줄 수 있다(기타 자세한 사항은 sitemaps.org 를 참고). Sitemap 클래스를 사용하기 위해 items() 메서드가 반드시 포함되어야 하는데, 위에서처럼 QuerySet 을 리턴해주면 사이트맵 제공을 위한 object의 목록을 만들어 준다. Django 에서는 Sitemap 클래스 내의 location() 메서드 혹은 location='value' 속성을 이용해서 <loc> 태그 안에 들어갈 URL을 제공해줄 수 있는데, 따로 명시하지 않으면 items()에서 가져온 object의 get_absolute_url()을 이용해 얻은 URL을 생성해 준다. <lastmod>는 해당 아이템이 최종 수정된 날짜로, 메서드 lastmod() 또는 속성 lastmod='value' 값으로 지정해줄 수 있다. 반드시 파이썬의 datetime 값으로 지정해야 한다. 이 블로그의 경우는 포스트마다 최근 수정한 날짜(modify_date)를 기록하고 있어 그 값을 lastmod 값으로 지정해주도록 메서드를 정의했다. <changefreq>는 메서드 changefreq() 또는 changefreq='value' 속성으로 지정해줄 수 있다. 속성으로 지정해 주는 경우 위처럼 'weekly' 또는 'always', 'hourly', 'daily', 'monthly', 'yearly', 'never' 등으로 지정해줄 수 있다. 이 속성은 검색엔진에 해당 내용이 얼마나 자주 바뀌는지를 알려 주는데, 그냥 참고용 정보일 뿐이고 검색엔진이 지정된 주기로 인덱싱하도록 명령을 내릴 수 있는것은 아니므로, 메서드를 이용해서 아주 엄밀하게 지정해줄 필요는 없을것같고 대략 위의 속성 중에 골라서 지정해주면 될 듯하다. <priority> 는 역시 메서드 또는 속성으로 지정할수 있는데, 0에서 1 사이의 값을 지정하면 된다. 지정해주지 않는 경우 기본 값은 0.5 이다. 이 값은 해당 사이트 내에서 현재 아이템이 얼마나 중요도를 갖는지를 검색엔진에 알려 주려는 목적이고, 다른 사이트와 비교해서 중요도를 나타내는 것은 아니기 때문에 무조건 높다고 좋은것은 아니다. 사이트 관리자가 재량껏 지정하면 되겠다.   #5. 위에서는 models.py 에 정의된 Post 모델에서 QuerySet을 읽어와서 각각의 item을 동적으로 제공했는데, 사이트의 메인 페이지나 기타 정적인 view의 사이트맵을 제공해야 할 필요가 있다. 이를 위해서 sitemaps.py에 정적인 페이지를 위한 클래스를 새로 만들어 준다. items() 에 urls.py 에서 지정한 view의 이름을 리스트 형식으로 리턴해 주고, 이를 urls.py의 sitemaps 변수에 포함시켜 주면 된다. 우선 위에서 작업한 sitemaps.py 에 다음 내용을 추가해준다.   상응하는 urls.py 의 내용은 다음과 같다.   앱 디렉토리 내의 urls.py   #6. 수정사항을 push 해서 반영해주고 도메인/sitemap.xml 로 접속해보면 xml 사이트맵이 보이는 것을 확인할 수 있다.   그러나 잘 보면 사이트 주소가 example.com 으로 우리 홈페이지의 주소가 아닌 것을 볼 수 있는데, 이는 Django admin 에서 수정해 주어야 한다. Admin 화면으로 접속해 보면 'Sites' 항목 아래에 sites 가 있는것을 볼 수 있는데, 여기 들어가보면 site 이름이 example.com 으로 되어 있다.    이 부분을 클릭해서 원하는 도메인 이름으로 바꾸어 준다.   이후 사이트맵에 다시 접속해 보면 정상적으로 도메인이 변경되어 있는 것을 확인할 수 있다.   사이트맵을 작성해 놓으면 검색엔진이 크롤링하기가 수월해지고 그에 따라서 검색 결과에 사이트의 내용이 노출되는데도 도움이 되므로 가능하면 만들어 놓는 것이 좋겠다.

Django 프로젝트에서 robots.txt 파일 제공하기 

2020. 02. 17 IT/컴퓨터 > Django
  Robots.txt 는 웹페이지의 자료를 크롤링하는 검색 엔진 봇들을 위해 어떤 페이지는 정보를 수집해도 되고, 어떤 페이지는 수집을 금할 것인지 알려주는 역할을 하는 간단한 텍스트 파일이다. 검색 엔진 봇들은 홈페이지의 링크를 타고 다니면서 정보를 수집하고 이를 검색 결과에 보여 주므로 홈페이지나 블로그가 효과적으로 검색엔진의 검색 결과에 나오게 하기 위해서 설정을 잘 해 주는것이 중요할 것이다.   내용은 대략 알고 있었지만 사실 실제로 블로그를 만들기 전까지는 현실적으로 어떤 것이 문제가 될 만한 내용인지 와닿지는 않았다. 그런데 블로그를 도메인에 연결하고 공개를 하고 보니 한 가지 치명적인 문제가 발견되었다.    이 블로그는 글 작성후에 publish 버튼을 누르기 전에는 초안 상태로 저장되어 있다가 publish 버튼을 누르면 공개되는 방식으로 만들어져 있는데, 글 작성후 내가 분명히 publish 하지 않고 초안 상태로 놔 두었는데도 어느 정도 시간이 지나면 자꾸 저절로 publish 가 되는 버그가 발견된 것이다. 자동으로 실행되는 함수같은 것을 만든 적도 없는데 왜 이런 현상이 발생하는지 고민이었다.   그런데 서버 로그를 보니 구글 크롤링 봇이 페이지를 들러서 publish 링크를 누르고 다니는 것 같았다. 그래서 아직 publish 되지 않은 글들의 publish 링크에 봇이 접근하지 못하도록 해야 할 필요가 생겼다. 그동안 사이트에 robots.txt 가 없었는데, 구글 봇이 발간되지 않은 글들을 모아놓은 URL에 접근할 수 없도록 해당 내용을 robots.txt에 추가해 주었다. Django 프로젝트에서는 단순히 루트 디렉토리에 robots.txt만 업로드해 놓으면 검색 엔진이 파일을 찾을수가 없고, 따로 설정을 해서 제공해야 되는 것이라서 공부한 내용을 정리해 본다. 크게 세 가지 방법이 있다.   #1. 간단히 해결하려면 urls.py 에 직접 robots.txt 의 내용을 써주면 된다. lambda function 을 활용. 물론 HttpResponse 를 먼저 import 해주어야 한다. 이 방법은 파일 하나만 손대면 되어 간단하지만, robots.txt 의 규칙이 늘어나면  추가해주기가 번거롭고 urls.py 본연의 임무인 url 매핑 이외의 내용으로 파일이 너무 지저분해지는 단점이 있겠다. 원칙적으로 각각의 코드는 자기 본래의 역할에 충실하는 것이 올바른 코딩 방향이므로 이 방법은 별로 추천하고 싶지는 않다.       #2. Django-robots 앱을 사용하는 방법. 링크 - Django-robots documentation robots.txt 를 관리하기 위한 전용 앱이 있다. 를 입력해서 설치할 수 있고 대규모 프로젝트의 경우에는 이 앱을 사용하면 매번 robots.txt를 push 하지 않고도 편리하게 관리할 수 있다고 한다. 혼자 쓰는 블로그같은 소규모 프로젝트에는 직접 robots.txt 를 수정해 주는 정도로 충분한것같아 아직 사용해보지는 않았다.    #3. 실제 robots.txt 를 작성하여 업로드후 url을 지정해 주는 방법. 우선 robots.txt를 작성하여 원하는 디렉토리에 업로드한다. urls.py에서 경로를 정해 줄 것이기 때문에 아무데나 둬도 상관 없지만, 가급적 base.html 이 있는 프로젝트의 가장 root의 template 디렉토리에 넣는것이 관리 면에서 좋겠다. robots.txt를 업로드 후 프로젝트의 메인 urls.py 에 다음과 같이 설정해준다. 일반 html template 과 다르게 타입을 plain text 로 지정해 주는것이 추가된다. root template 디렉토리가 아닌 곳에 robots.txt를 둔 경우에는 적절하게 경로를 바꿔 주면 되겠다. 함수형 view를 사용할수도 있지만 generic class based view 인 TemplateView를 이용하면 간단하다.  robots.txt를 직접 읽어서 서빙해 주는 방식이다. 각각의 파일이 본래 목적에 맞는 동작을 하는 점에서 1번보다는 더 좋은 방식이다. 검색 규칙을 바꾸는 것도 직접 txt 파일만 수정하면 되기 때문에 편리하다. 파일의 규칙이 자주 바뀌는 경우 로컬에서 파일 수정후 서버에 push 해 줘야 하는것은 귀찮을 수도 있겠다. 하지만 이미 완성된 사이트라면 robot 검색 규칙을 바꿀 일은 별로 없을 듯.   이외에 사용하는 서버에 따라 직접 robots.txt를 업로드하고 서버 세팅을 변경해서 Django 를 거치지 않고 제공하는 방법도 있지만, 일을 두 번 해야 하므로 번거롭고 서버마다 세팅이 달라 일괄 적용하기 어려운 점이 있을 것이다. 이 블로그에서는 #3의 방법으로 사용중이다. robots.txt를 설정해주면 검색엔진이 적절히 자료를 수집하는데 도움을 주고 불필요한 수집이나 오동작을 방지할 수 있으므로 어느 홈페이지든지 적절하게 설정해 주는것이 좋겠다.   다만 robots.txt 의 내용은 어디까지나 로봇에게 일러 주는 권장사항일 뿐 기술적으로 접근을 차단하는 것은 아니다. 정상적인 로봇이라면 권장사항을 준수하면서 크롤링하겠지만 악성코드의 경우 이를 무시하고 돌아다닐 수도 있으므로 백엔드에서 근본적으로 접근을 차단할 방법은 별도로 강구해야 할 것이다.   (다시 원래의 publish 기능 얘기로 돌아가면, 근본적으로는 해당 문제는 프로젝트의 소스 코드를 수정해서 해결해야 했다. Publish 기능이 담긴 view를 장고의 @login_required 데코레이터를 이용해서 막아 주어서, 글을 publish할 수 있는 링크는 로그인한 유저에게만 노출되도록 권한 조정을 통해서 해결했다.)

Disqus 사용시 자동으로 링크가 생성되는 문제 해결 

2020. 02. 16 IT/컴퓨터 > Blogging
  블로그를 만들고 나서 댓글 시스템도 만들고 싶었지만 여력이 되지 않아 일단 댓글 전문 시스템인 Disqus를 포스트 하단에 달아 놓았다. 그러고 나서 블로그에 글을 올리다 보니, 본문에 웹사이트 주소같은 문자열이 들어가 있는 경우 저절로 링크가 생성되는 현상이 발생하는 것을 발견했다. 얼핏 보면 신기해 보이지만, 실제로 연결을 의도한것도 아닌 곳에 쓸데없이 링크가 되어 거슬리는 점이 많았다. 의도하지 않은 기능이므로 제거를 하고 싶었는데, 처음에는 본문 텍스트에 변화가 있으니 당연히 CK 에디터에 딸린 기능으로 생각했다. CK 에디터 관련 문서만 한참 뒤졌는데 도저히 원인을 찾을 수가 없어서 골치가 아팠다. 링크의 정체를 파악하기 위해 우선 개발자 도구(대부분 브라우저에서 F12키를 눌러 사용할수 있다)를 이용하여 inspection 을 해 보면, 다음과 같이 "vglnk" 라는 클래스가 달린 <a> tag이 자동으로 생성되어 있는것을 발견할 수 있다.     일단 급한대로 jQuery 를 이용해서 vglnk 클래스가 달린 <a> 태그를 제거해주는 코드를 짜서 페이지 아래에 덧붙여 놓았지만 아무래도 임시방편이라 마음에 들지 않았다. 근본적으로 링크 생성 자체가 되지 않게 하고 싶은데..구글링을 하다 보니 Disqus와 관련해서 발생하는 문제인 것을 알게 되었다. 괜히 애꿎은 CK에디터 관련 자바스크립트 파일만 수없이 고쳤다 복구했다 했네.   일단 Disqus 에 접속해서 댓글 창이 연동된 페이지의 Admin 창을 찾아 간다. 주소로 바로 찾아 가려면 로 가면 된다.     Admin 창에서 Settings -> Advanced 에 들어가 보면 Tracking 과 Affiliate link가 체크되어 있는것을 볼 수 있는데, 이것들을 해제해 주면 자동으로 링크가 걸리는 현상이 사라지게 된다.   Disqus 와 제휴된 사업자들의 웹사이트로 방문객을 유입시키기 위해 활성화된 일종의 광고 기능인데, 그대로 두면 꽤나 거슬린다. 설치 과정 중에 따로 설명을 못 본것같은데 슬쩍 끼워넣다니..어디 깨알같은 글씨 안에 포함되어 있었으려나? 다행히 알고 나니 해제하는 절차는 복잡하지 않고, Disqus 사용상 특별한 페널티 없이 해제할 수 있어서 바로 해제해 주었다.  여튼 댓글 시스템이 어딘가에 종속되어 있는것도 썩 마음에 들지는 않아서 장기적으로는 자체 댓글 시스템을 개발해서 달아 보려고 한다.

Pythonanywhere.com에 Django 프로젝트 배포하기 (2) 

2020. 02. 15 IT/컴퓨터 > Django
이전편에 이어서 pythonanywhere.com 을 이용해 Django 프로젝트를 배포해 본다. 이전 글: Pythonanywhere.com에 Django 프로젝트 배포하기 (1)     #16. Web tab에 가면 [ 자기id.pythonanywhere.com ] 도메인 이름을 확인할 수 있는데, 이 시점에서 브라우저에 이 URL을 입력해보면 기본 Hello, World! 앱을 볼 수 있다.     #17. 우리가 만든 가상 환경의 이름을 Web 탭 중간쯤에 있는 Virtualenv: 섹션에 입력해준다. 주소는 [ /home/자기id/.virtualenvs/myproject ] 와 같다. 기억이 잘 나지 않는 경우 dashboard에서 Files 탭에 가서 루트 디렉토리에서 .virtualenvs/ 디렉토리로 들어가 보면 자기가 만든 가상환경의 이름을 확인할 수 있다. 가상환경을 등록하고 나면 아래에 그 가상 환경에서 작업할 수 있는 console 링크가 생긴다.   #18. Virtualenv 위의 Code: 섹션에 source code 를 입력해준다. 형식은 [ /home/자기id/프로젝트 디렉토리 이름 ] 과 같다. manage.py 가 있는 디렉토리가 맞는지 확인하고 입력한다.   #19. Code 섹션에 있는 WSGI configuration file을 클릭하면 편집기가 나온다. 중간의 Hello world 관련 부분은 주석 처리하거나 지워서 Hello, World! 화면이 나오지 않게 해주고   #20. 같은 파일 아래쪽을 보면 DJANGO 설정 부분이 있는데, 이 부분의 주석처리를 없애 실행되도록 만들어 주면 된다. 이때 path 에는 아까 Code 섹션에서 지정해준 source code 디렉토리 (manage.py가 있는) 를 지정해주고, settings 경로는 path 디렉토리 아래에 있는, settings.py 가 있는 디렉토리를 지정해 준다.   #21. 이제 거의 다 되었는데, 브라우저에 자기id.pythonanywhere.com 주소를 입력해 본다. 이때 다음과 같은 에러 메세지가 나올 수 있다. 이를 해결하기 위해 #20에서 지정한 settings.py 파일을 열고, ALLOWED_HOSTS 에 [ 자기id.pythonanywhere.com ] 을 추가해 준다.   ALLOWED_HOSTS 수정 후 프로젝트의 첫 페이지 화면이 로딩된 것을 확인할 수 있다.    #22. 그러나 사실 아직 static file 경로가 설정되지 않아 css 파일등 정적 파일이 로딩되지 않았다. 우선 #20에서 지정해주었던 settings.py 를 찾아 STATIC_URL과  STATIC_ROOT 을 지정해 주어야 한다. 주의할 점은 STATIC_ROOT를 STATIC_URL과 겹치지 않는 이름으로 지정해 주어야 한다. 여기서는 URL은 /static/, ROOT는 루트 디렉토리 아래의 /web_staticfiles/ 라고 지정했다.   #23. 이후 Web tab으로 돌아와 Static files: 섹션을 찾아 URL 을 지정해 준다. #22에서 지정했던 디렉토리를 입력해 주면 된다.    #24. Bash console 을 열고, 커맨드를 실행해 준다. 이 커맨드를 실행하면 프로젝트 내의 정적 파일들을 위에서 지정해준 STATIC_ROOT 디렉토리로 모아서 실제 웹 서비스가 가동될 때 이곳에서 파일을 읽을 수 있게 해 준다.   #25. 이제 css 파일이 정상적으로 로딩되어 지정해준 폰트가 적용된 것을 볼 수 있다.     이상으로 pythonanywhere.com 에서 Django 프로젝트를 배포해 보았다. Microsoft azure나 Heroku 등의 서비스에서 배포하려고 하다가 설정이 너무 복잡하고 에러가 많아 어려움을 겪었는데, pythonanywhere에서는 상대적으로 간단히 배포가 되는것같다. 호스팅 업체 규모가 크지는 않은것 같아서 대규모 프로젝트에서의 동작은 어떨지 모르겠지만, 개인용 블로그같은 사이트를 쉽게 배포할 때 이용하기는 좋을 것같다.

Pythonanywhere.com에 Django 프로젝트 배포하기 (1) 

2020. 02. 15 IT/컴퓨터 > Django
  국내 웹 개발 환경은 PHP 가 대세이고 호스팅 업체들 역시 대부분 PHP 호스팅만 지원하는 실정이라 장고 프로젝트를 배포하기 쉽지 않다. 서버 호스팅을 하면 되겠지만 맨땅에 리눅스부터 깔고 세팅할 것이 많아 초보자로서는 어려운 점이 많았다. Pythonanywhere.com 이라는 사이트가 있는데, 번거로운 세팅작업을 최소화하고 쉽게 Django 프로젝트를 배포할 수 있도록 해 주는 사이트이다. 이름에서 알 수 있듯이 파이썬 언어에 최적화된 서비스를 제공한다. 프로젝트 배포는 가끔 하게 되는 일이라 처음 세팅 내용은 할때마다 약간씩 삽질을 하게 되는데, 오늘은 다음 프로젝트를 위해 복기도 할 겸 배포 작업을 순서대로 정리를 좀 해보려고 한다.   #1. GitHub을 통해서 배포가 이루어지기 때문에 미리 프로젝트를 Github에 프로젝트를 업로드해서 repository를 만들어 두어야 한다.   #2. 링크 - Pythonanywhere 간단한 가입과정을 거치면 요금제를 선택할 수 있다. 이 블로그는 Hacker 계정으로 운영중인데(월 5달러), 무료인 Beginner 요금제도 배포하고 실제 동작을 체크하는 데에는 문제가 없다. 다만 자기의 domain 을 쓸 수 없고 주어지는 도메인을 써야 한다. 가입후 등록한 email 주소로 오는 확인 메일을 confirm 해주면 정상적으로 계정을 사용할 수 있다.   #3. 로그인하면 볼 수 있는 Dashboard에서는 console 창을 띄우거나 직접 파일관리를 하는 등의 여러 작업을 할 수 있는데, 우선 배포를 위해 Web app을 만들어야 하므로 "Web" 탭으로 들어가 Add a new web app 을 클릭한다.       #4. 도메인 이름을 지정해줄 수 있는데, 아직은 도메인이 없으므로 자동으로 생성해주는 도메인을 사용한다. 만약 도메인을 연결하려는 경우에는 직접 도메인을 입력해주면 되는데, 이때 앞에 www가 포함된 도메인인지 아닌지를 정확히 입력해줘야 한다. 이것을 정확히 하지 않으면 오류가 나면서 페이지에 접속이 안되는데, 나중에 수정이 안되고 web app 전체를 지우고 다시 만들어야 되기 때문에 처음에 신경쓰는것이 좋다.   #5. Django 프로젝트이지만, "Django" 를 클릭하면 처음부터 Diango project를 만드는 과정이 시작된다. 지금처럼 이미 로컬에서 만들어진 프로젝트가 있는 경우는 "Manual configuration" 을 선택해주어야 한다. 수동 구성을 클릭하면 설치할 Python 의 버전을 선택할 수 있는데 프로젝트에 사용한 버전으로 골라주면 된다.     #6. 무료 계정의 경우 3개월동안 접속이 없으면 계정이 비활성화된다. 계정을 유지하려는 경우 버튼을 클릭해서 3개월동안 사이트를 활성화하는 작업을 해준다. 유료 계정의 경우에는 필요없는 작업이다.   #7. 다음 작업을 위해 Console tab으로 가서 Bash console을 연다.         #8. 먼저 가상환경을 만들어줘야 한다. 커맨드로 자신이 사용하는 파이썬 버전과 사용할 가상환경의 이름을 입력해주면 된다. 필요한 파일이 설치된 후 프롬프트 앞에 (myproject) 처럼 가상환경 이름이 보이면 정상적으로 설치된 것이다.   #9. Django 및 필요한 패키지들을 가상환경에 설치해준다. 위의 명령으로 현재 설치된 패키지들을 볼 수 있다. Django 설치를 위해 위와 같이 프로젝트에 사용된 버전을 명시해서 설치해준다. 버전을 생략하고 pip install django 만 입력하면 최신버전이 설치된다.  기존에 설치된 버전을 최신 버전으로 업그레이드하는 경우에는 다음 명령어를 입력하면 된다     #10. Django가 설치된 위치를 로 확인할 수 있다.   #11. 이제 Github의 repository로 가서 repository의 주소를 복사해 온다. Clone or download 버튼을 누르면 주소가 표시되는데, 주소 옆의 클립보드 버튼을 누르거나 Ctrl+C 로 복사할 수 있다.   #12. 다시 console로 돌아와서 명령어로 원격 repository를 다운로드한다.   #13.  ls 커맨드로 디렉토리를 확인하고 해당 디렉토리에 들어가보면 (master) branch 를 확인할 수 있다. 해당 디렉토리에 manage.py 파일이 있어야 정상적으로 작업하고 있는 것이다.   #14. 데이터베이스 테이블을 만들고 migration을 적용시키기 위해 순서로 커맨드를 실행해 준다.   #15. 사이트 관리자인 superuser 계정을 명령을 이용해 만들어준다.   이제 다시 pythonanywhere의 Web tab으로 돌아가 세부 설정을 해 주어야 한다.  다음편에 이어서.. Pythonanywhere.com에 Django 프로젝트 배포하기 (2)
  • 1
  • 2
  • 3 (current)