DjangoORM에서 SQL Driver 지정해 Query & Pandas DataFrame 얻어내기

들어가며

장고의 매력적인 기능 중 하나는 ORM을 통해 SQL을 직접 작성하지 않아도 된다는 점입니다. 즉, 우리가 파이썬 코드를 작성하면 모델 매니저와 SQL Driver를 거쳐 실제로 SQL문으로 만들어주는 일을 장고가 대신해줍니다.

그리고 장고가 DB를 바라보는 방법은 settings.py파일 내 DATABASE설정 통합니다. 그리고 default로 설정된 데이터베이스를 참고해 ORM을 제공합니다. 하지만 이점은 장고 프로젝트 하나에서 여러 데이터베이스를 바라보며 사용할 경우 문제가 발생합니다.

django에 MSSQL 연결하기

이번 글은 macOS에서 개발하는 경우입니다.

Django와 MSSQL, 그리고 개발 환경이 macOS라면 상당히 연결해 사용하기 어려운 조합입니다.

Django에서 MSSQL을 지원하는 라이브러리는 몇가지 있지만 Django 공식 문서에서 MSSQL을 지원하는 ORM 라이브러리로 소개하는 django-mssql의 경우 django 1.8까지만 지원하는 문제가 있습니다.

하지만 현재(2018-02-02 기준) 가장 최신 장고 버전은 무려 2.0.2입니다. 상당히 오래된 버전만을 지원한다는 문제가 있습니다.

따라서 다른 라이브러리를 사용할 필요가 있습니다. 이번에는 Python3와 Django2.0을 모두 지원하는 django-pyodbc-azure를 사용합니다.

Django CBV: queryset vs get_queryset() 삽질기

요약: queryset은 request 발생시 한번만 쿼리셋이 동작하고, get_queryset()은 매 request마다 쿼리를 발생시킨다. 조건이 걸린 쿼리셋을 쓸때는 get_queryset()을 오버라이딩하자.

사건의 발단

ListView안에서 체크박스로 ForeignKey로 연결된 장고 모델 인스턴스를 저장(.save()를 호출)하는데 저장 후 모델 인스턴스의 값을 확인하는 뷰에서는 결과값이 저장 전의 데이터로 나타났었다.

1
2
3
4
5
6
7
8
9
# 문제의 코드..
class OrderMatchingList(ListView):
class Meta:
model = Order

queryset_list = Order.objects.filter(status__gte=5) \
.select_related('education', 'region') \
.prefetch_related('orderdetail_set')
queryset = sorted(queryset_list, key=lambda x: x.start_date())

사실 지금은 코드를 보면 queryset에서 sorted된 값을 반환하고, 이경우에는 쿼리셋 자체가 저 변수로 할당되어버려 다음 request에서 쿼리가 돌지 않는다는 것을 쉽게 찾을 수 있다. 하지만 원래 한번 안보이면 잘 안보이는 법.. 심지어 이 경우에는 Exception이 나는 것도 아니기 때문에 더 찾기 어려웠다.. (ㅠㅠ)

삽질의 시작

여러가지 가정을 할 수 있는 상황이었다.

  • 혹시 브라우저가 리스트를 캐싱하고 있던건 아닐까? (브라우저 캐시)
  • 장고가 View의 Response를 캐싱하고 있는걸까? (장고 캐시)
  • 혹시 DB에 save()가 안된(아예 DB가 업데이트가 되지 않은) 것은 아닐까?
  • 장고 queryset에 캐싱이 되어있었을까?
  • AJAX call이 비정상적으로 이루어진 것은 아닐까?
  • 아니면, 아예 내 View 로직이 잘못된 것은 아닐까? (CBV인데?)
  • select_relatedprefetch_related에서 캐싱이 발생하는걸까?

이런저런 가정을 하고 하나씩 체크를 해보기로 했다.

아래부분에서는 django 로직과 관련된 삽질만 다뤘습니다. JS쪽은 문제가 없었거든요.

widgets:

첫번째 삽질: “브라우저가 캐싱을 하고 있는건 아닐까?”

만약 브라우저가 HTML파일을 캐싱하고 있다면

  • 캐시 삭제후 강력 새로고침을 하거나,
  • 다른 브라우저로 접근하면

정상적인 화면이 나와야 했다.

그러나… “#망했어요”

브라우저가 캐싱하고 있는게 아니었고, 다른 브라우저에서도 기존(업데이트 전)값을 가져왔다.

widgets:

두번째 삽질: “장고가 template 렌더링 된것을 캐싱하는게 아닐까?”

사실 장고에서 response는 따로 캐싱을 명시적으로 하지 않으면 쿼리가 새로 발생해야 하는 경우에는 캐싱을 하지 않는다.

하지만 일단 template을 재 렌더링 하지 않는게 아닐까… 하는 생각에 아래와 같은 부분을 추가해 보았다.

1
2
3
{% raw %}{% for object in object_list %}
{{ object }} 이건 object다
{% endfor %}{% endraw %}

역시 .. “응 아니야~ 장고 일 잘하고 있음”

템플릿은 렌더링이 충분히 잘 되고 있었다.

뭐가 문제일까?

widgets:

세번째 삽질: “.save() 메소드의 사용을 잘못한게 아닐까?”

아예 다음번에는 DB에 저장이 되지 않고 있는게 아닌가.. 하는 생각에 save()update()의 사용법을 찾고, force_insert=True와 같은 옵션을 넣어보기도 했다.

1
2
3
4
5
6
7
8
9
# view.py 파일에서...
# ...
for m_pay in mentor_payment_list:
if str(m_pay.pk) in cleaned_keys:
m_pay.status = 1
else:
m_pay.status = 0
m_pay.save(update_fields=['status'])
# ...

.save()는 모델 인스턴스에 적용하는 케이스이고, .update()는 쿼리셋에 적용하는 방법이다. save()의 경우 모델 인스턴스를 가져오기 위해 SELECT 쿼리를 한번 날리고 값을 변경 후 UPDATE를 해주는 방법이라면, update()는 쿼리 자체를 SELECT쿼리로 날리는 방식이다. 따라서 만약의 경우 .update()를 실행 중 다른 요청에서 값이 변경되었다면 그 Transaction이 손실될 수 있고, 모델 인스턴스의 값 자체를 이용해 업데이트하는 방법은 사용하기 어렵다. (물론 사용은 가능하지만 SELECT쿼리같이 .get()으로 한번 가져와야 하기때문에 큰 의미는 없습니다. 여전히 중간에 값이 변경되었을 경우에 기존 값(get)에 대한 불가능하고요.)

m_pay.save(update_fields=['status'])에서는 save()update_fields 리스트를 넣어주었다. 일반적인 save()함수가 인스턴스 전체를 변경하는 UPDATE문을 사용하지만 update_fields가 있는 경우에는 force_insert가 자동으로 True가 되며 동시에 해당되는 Column만 update가 일어난다.

게다가 update_fields를 넣기 전에도 이미 잘 작동하던 코드.

무엇이 문제일까? 문제는 미궁속으로..

widgets:

네번째 삽질: “select_relatedprefetch_related에서 캐싱이 발생하는건 아닐까?”

장고에서 select_relatedprefetch_related는 기본적으로 한번에 데이터를 가져와 queryset 자체에 캐싱을 하는 전략인데.. 혹시 여기에서 ‘과도한 캐싱’이 발생하고 있는건 아닐까?

그렇다면 장고의 캐싱을 강제로 없애는 never_cache 데코레이터를 사용하면 어떨까? 하지만 지금 뷰는 CBV니까.. @method_decoratornever_cache를 전달해 주면 되겠다!

1
2
3
4
5
from django.views.decorators.cache import never_cache

@method_decorator(never_cache, name='dispatch')
class OrderMatchingList(SuperuserRequiredMixin, LoginRequiredMixin, ListView):
# ...

물론, 당연히, 캐시 문제가 아니었기 때문에 안되는 것은 당연했다.

widgets:

다섯번째 삽질, 여섯번째, 일곱 … 그리고 더 많은 삽질 끝에서의 허무

도대체 뭐가 문제인거지? ListView가 아예 문제인가? 이런 고민을 하다가 결국 django의 ListView자체를 뜯어보는데 눈에 들어오는 MultipleObjectMixin.

1
2
3
4
5
6
7
class MultipleObjectMixin(ContextMixin):
# ...
queryset = None
# ...

def get_queryset(self):
# ...

헐. querysetget_queryset은 다른데.

widgets:

해결 & 평화

사실 이 문제가 생긴건 DB에서 정렬하는 대신 파이썬 View에서 쿼리셋을 정렬하는 방식으로 사용하려다보니 생긴 문제였다.

모델 내부의 start_date()에 따라 정렬하는 방식을 쿼리셋 내부에서 구현이 어려워 파이썬의 sorted를 이용했는데, 이 sorted된 결과물이 queryset 변수에 담겨 새 request에도 같은 결과를 반환하게 된 것.

따라서 다음과 같이 get_queryset으로 변환해주어서 깔끔하게 해결되었다.

1
2
3
4
5
6
7
8
9
class OrderMatchingList(ListView):
class Meta:
model = Order

def get_queryset(self):
queryset_list = Order.objects.filter(status__gte=5) \
.select_related('education', 'region') \
.prefetch_related('orderdetail_set')
return sorted(queryset_list, key=lambda x: x.start_date())

사실 DJDT(Django Debug Toolbar)를 사용하며 쿼리의 개수를 확인해보는데 첫 요청시에는 6개의 쿼리가 가는데 비해 두번째 요청부터는 3개의 쿼리만이 실행되고, 그마저도 데이터를 가져오는 쿼리는 없고 세션/로그인등의 비교만 쿼리를 실행하고 있다는 것을 발견해 쿼리셋쪽의 문제라는 것을 알 수 있었다.

여담

문제의 코드 부분(아래)에서 select_relatedprefetch_related를 제거하면 쿼리수는 몇십개로 증가하지만 데이터 자체는 정상적으로 가져왔다. 이건 또 왜그랬을까?

1
2
3
4
5
6
7
8
9
# 문제의 코드..
class OrderMatchingList(ListView):
class Meta:
model = Order

queryset_list = Order.objects.filter(status__gte=5) \
.select_related('education', 'region') \
.prefetch_related('orderdetail_set')
queryset = sorted(queryset_list, key=lambda x: x.start_date())

Deploy Django to MS Azure with Fabric3

한국어 버전은 Django MS Azure에 Fabric으로 배포하기에서 보실 수 있습니다.

This guide covers about deploying DjangoGirls Tutorial to MS Azure Virtual machine(Ubuntu 16.04 LTS) with Fabric3.

You’re probably participant in DjangoGirls Tutorial Workshop and you’ll be now on ‘deploy’ step on it.

Today we’re going to deploy our django project to Azure which is provided with MS.

If you didnt’ register your AzurePass yet, please precede this guide first: Register Azure and redeem AzurePass

(If Windows) Using cmder

You can’t use linux commands like git or ssh on your cmd, so we’re going to use great shell program which named cmder.

First, click this link:cmder.zip to download cmder. (It may take times.)

Second, unzip downloaded cmder.zip file. (It’ll take some times too.) And then you got this!:

Execute cmder.exe in this folder. If you execute cmder.exe as a first time you’ll be see Security Warning like this: just click RUN.

And one time more, if you execute cmder for the first time, there will be another warning like this: click first option, “Unblock and continue”.

It’ll take some times when you run cmder first time. This wouln’t appear next time, so please wait for a moment!

If you see this, you’re ready to use cmder NOW!

If you’re following DjangoGirls Tutorial, you probably made folder named djangogirls. Let’s get into it.

cd is command to ender the folder! Let’s get into djangogirls folder with cd djangogirls.

Let’s start deploy then.

Deploy Azure Virtual machine

You’ll see this screen if you logged in to Azure Portal.

Azure Portal Dashboard

Let’s make Virtual machine with clicking VirtualComputer(가상 컴퓨터) button.

Now let’s add Virtual machine with ‘+Add’ button.

If you click + Add button, you’ll see another options which provides many OS. But we’re going to use Ubuntu Server today.

If you clicked Ubuntu Server there’ll be server lists like this: we’ll use Ubuntu Server 16.04 LTS.

Then you’ll see Create button. Click it!

You’ll see configure window when you click Create button. Fillout blanks like picture lower.

Username should be django (surelly this is not critical but you may encounter issues.

You may set your password on your own, but it shoud be longer/equal than 12. Please remember not to reset it later.

Select locaiton on Korea Centeral or SouthEast Asia(which available one).

Now we have to choose server size. We’ll setup just one django server so we’ll choose DS1_V2, the left one.

Don’t worry, you won’t be charged :)

Next step you have to setup storage settings. Just select Use managed disks to ‘Yes’.

And then click Network Security Group(Firewall) settings. After click on it, you’ll see pre-configured setting SSH (TCP/22). We’re going to add HTTP (TCP/80)

Click + Inbound Rule add Button, and fillout blanks like this and click OK button.

Now default settings are finished! Just click OK button.

And one more time, click confirm button.

And lastly, click confirm button more! I know you’re tired with confirm button, but this is process of Azure :)

If you see your azure dashboard again like this, your server deployment is finished :)

Please wait until your server is successfully installed! (This will take upto 5mins.)

Your browser will redirected to your server info page when your server is successfully installed.

Get Azure Server Configurations

You can access to your server info with clicking server icon-which tells Running.

On this page you can see your server’s ‘Public IP Address’. ip is set of numbers which provides your computer access to internet. We can upload and deploy our django project through this ip.

You can see this example server’s ip, 13.67.60.234. Surelly we can access to our server with this numbers but we can’t remember easily with it.

So we’re going to use domain like djangogirls.com to that ip.

First of all, copy(CTRL+C) your virtual machine’s ip!

Get free domain and connect to Virtual Machine

You may know about popular domains like .com or .net. But they are paid one(10 dollars per year) so we’re going to use free domain.

Let’s go to Dot.tk.

This Dot.tk provides .tk domains as free! I’ll check djangogirls-seoul-tutorial-en.tk as example. You should think of your own domain name and click Check Availability!

Oh, it’s available! Just click ‘get it now’ button and add to cart.

You’ll see this page when you clicked ‘checkout’ button. Just click ‘Use DNS’ button and input ip address of your virtual machine(azure) and click ‘Continue’.

If you forgot ip address of your virtual machine, go to Azure portal and check your machine’s ip again!

You’ll see checkout page and you have to login. You can login with your social media account like Google or Facebook!

Sometimes there are some errors(404 or others..) then you can restart from “Get free domain and connect to Virtual Machine” on this guide.

If you successfully logined, you’ll see form to input your info, but you don’t have to fill it all. Just click Agress Terms and conditions and Conitnue button, your order will be finished!

Great! You’ve just connect your own domain to your server!

Install Fabric3

Now your server is connected with yourdomainname.tk domain. But if you try to access to that address, you can see nothing at all.

Because your server doesn’t have any django code and ofcourse, even django!

We’ll upload and deploy our django project with just one command line through Fabric3.

Let’s install fabric3 on our computer. You can install fabric3 with this command:

1
pip install fabric3

Remember: NOT fabric BUT fabric3! Don’t forget 3. fabric is python2 project.

Downlaod fabfile.py and edit deploy.json

Download Fabfile for Django and unzip it.

You can see deploy.json and fabfile.py inside of it. Move 2 files into your django folder(where manage.py exists)

Inside deploy.json, we can edit our server(virtual machine) info.

1
2
3
4
5
6
7
8
9
{
"REPO_URL":"Your Github Repository URL",
"PROJECT_NAME":"DjangoProject folder's name(where settings.py exists)",
"REMOTE_HOST":"Your domain(ex: djangogirls-seoul-tutorial-en.tk )",
"REMOTE_USER":"django",
"STATIC_ROOT":"static",
"STATIC_URL":"static",
"MEDIA_ROOT":"media"
}

Change REPO_URL, PROJECT_NAME, REMOTE_HOST. Other values are already setup for djangogirls tutorial we followed.

Every values must be in “”!

Upload and deploy code thorugh Fabric3

We can use fabric through fab command. Like this: fab new_server, fab deploy, fab create_superuser. This commands will execute commands on remote server(azure virtual machine which we made)

When you use fabric for new server, just type this command and execute: fab new_server. this will install python3, apache2, and mod_wsgi to run django.

1
fab new_server

When you edit django code and committed & pushed to github, then use fab deploy command. This will fetch latest code on github and migrate db.

1
fab deploy

When you want to create superuser, just execute fab create_superuser and there’ll be creating superuser prompt.

1
fab create_superuser

Whoa!

You’ve just upload and deploy REAL working web service on Azure! Congratulation!

Django MS Azure에 Fabric으로 배포하기

If you looking for English version, goto Deploy Django to MS Azure with Fabric3.

이번 가이드에서는 DjangoGirls Tutorial를 Fabric으로 Azure 가상 컴퓨터(Ubuntu16.04LTS)에 올리는 과정을 다룹니다.

지금 이 글을 읽고 있는 분들은 아마 장고걸즈 워크숍에 참가해 DjangoGirls Tutorial을 따라가다 이제 배포를 해볼 단계에 도착하셨을거에요.

오늘 우리가 만들어본(만들고 있는) Django 프로젝트를 MS가 서비스하는 Azure(애저)에 배포해보는 시간을 가져볼거에요.

만약 여러분이 AzurePass를 아직 계정에 등록하지 않았다면, Azure 가입하고 AzurePass 등록하기를 먼저 진행해 주세요.

(윈도우의 경우) cmder 설치하기

윈도우에서는 gitssh등의 명령어를 cmd에서 바로 사용할 수 없어요. 그래서 우리는 cmder라는 멋진 프로그램을 사용할 거에요.

우선 cmder.zip을 클릭해 cmder를 받아주세요. (84MB정도라 시간이 조금 걸릴거에요.)

다운받은 cmder.zip 파일의 압축을 풀어주세요.(이것도 시간이 조금 걸릴거에요.) 그러면 다음과 같은 내용이 보일거에요.

여기 있는 cmder.exe 파일을 실행해주세요. 실행하면 아래와 같은 Security Warning이 뜰 수 있어요. RUN을 눌러주세요.

만약 여러분이 cmder를 처음 실행하신다면 아래와 같은 워닝이 뜰거에요. 제일 첫번째 옵션인 “Unblock and continue”를 눌러주세요.

첫 실행시 아래 화면에서 약간 시간이 걸릴 수 있어요. 다음번 실행부터는 뜨지 않을테니 잠시만 기다려주세요!

아래 화면이 뜨면 여러분이 멋진 cmder를 쓸 준비를 마친거랍니다!

장고걸즈 튜토리얼을 따라오는 중이시라면 djangogirls라는 폴더를 만드셨을거에요.

폴더로 이동하는 명령어가 cd입니다! cd djangogirls라고 입력해주세요.

이제 배포를 진행해볼게요.

Azure 가상컴퓨터 만들기

Azure Portal에 들어가 로그인 하시면 아래와 같은 화면을 볼 수 있습니다.

Azure Portal 초기 대시보드

이제 대시보드 왼쪽의 메뉴에서 가상 컴퓨터를 눌러보시면 아래와 같은 화면이 나옵니다.

이제 가상 컴퓨터를 추가해봅시다.

+ 추가 버튼을 눌러주시면 아래와 같은 수많은 선택지가 나오는데요, 우리는 그 중에서 Ubuntu Server(우분투 서버)를 사용할거랍니다. Ubuntu Server를 클릭해주세요.

우분투 서버를 클릭하면 아래와 같이 서버 버전들이 나옵니다. 우리는 오늘 Ubuntu Server 16.04 LTS를 사용할거에요.

우분투 서버 16.04를 선택하고 나면 아래와 같이 만들기 버튼이 나올거에요. 버튼을 눌러주세요.

만들기 버튼을 누르면 아래 사진처럼 기본 사항을 설정하는 창이 나올거에요. 내용을 화면 사진 그대로 채워주세요.

사용자 이름은 가이드 다음부분에서 이용할 django로 하셔야 합니다.

암호는 각자 사용하는 암호를 입력하시면 되는데요, 12자리 이상을 요구하기 때문에 약간 어려우실 수 있어요!

위치는 대한민국 중부/남부로 해주세요. (안되는 경우 아시아 남동부로 해주세요!)

이제 서버의 크기를 골라야 하는데요, 오늘 우리는 장고 서버만을 띄울 것이기 때문에 가장 왼쪽에 있는 DS1_V2를 이용할거에요.

AzurePass를 등록하면 돈을 지불하지 않아도 되니 걱정하지 마세요!

이제 다음으로 넘어가면 저장소 설정을 해야 해요. 이부분에서는 ‘관리 디스크 사용’을 ‘예’로 클릭해주세요.

그 다음으로는 아래쪽의 네트워크 보안 그룹(방화벽)을 클릭해 주세요. 클릭하시면 아래와 같이 SSH (TCP/22)만 인바운드 규칙에 들어가 있는 것을 확인할 수 있어요. 우리는 여기서 HTTP (TCP/80)을 추가해 줄 거에요.

+ 인바운드 규칙 추가 버튼을 눌러주시고 사진과 같이 칸을 채워주시고 확인 버튼을 눌러주세요.

이제 설정이 모두 끝났어요! 아래쪽의 확인버튼을 눌러주세요.

다시 한번 확인 버튼을 눌러주세요.

이제 정말로 다음 확인버튼만 누르면 서버 설치가 끝나요!

이제 조금만 기다려주시면 서버 설치가 끝난답니다!

아이콘의 설명이 Creating에서 Running으로 바뀌면 설치가 끝난거에요.

Azure 설정 확인하기

Running으로 바뀐 아이콘을 클릭해주시면 아래 화면으로 들어올 수 있어요.

애저에서 가상컴퓨터가 생기면 공용 IP 주소라는걸 하나 갖게 된답니다. ip라는 것은 서버나 컴퓨터가 인터넷에 접속할 수 있게 해주는 일련의 번호인데요, 우리는 이 ip를 통해 우리 장고 프로젝트를 서버에 올리는 작업을 진행할 수 있어요.

지금 화면에 보이는 가상컴퓨터의 ip는 52.231.30.148인데요, 이렇게 숫자로만 되어있으면 우리는 기억하기가 어려워요.

그래서 djangogirls.com와 같이 사람이 이해하고 외우기도 쉬운 도메인을 저 ip주소에 붙여줄거에요.

자, 우선 여러분의 가상 컴퓨터의 ip를 복사(Ctrl+C / CMD+C)해두세요!

무료 도메인 얻어 가상컴퓨터에 연결하기

.com, .net와 같이 유명한 도메인은 돈을 주고 사야한답니다.(1년에 만원정도 나가요) 하지만 우리는 오늘 무료 도메인을 연결해 볼 거에요.

우선 Dot.tk로 들어오세요.

이 Dot.tk에서는 .tk 도메인을 무료로 제공하고 있어요. 우선 djangogirls-seoul-tutorial이라는 이름으로 찾아볼게요. 값을 입력하고 Check Availability를 눌러주세요!

여러분은 여러분이 원하는 주소를 검색해보세요! (ex: myfirstdjango 등등)

오, 다행히 주소가 남아있어요. 이제 Get it now!버튼을 눌러 장바구니에 담아볼게요.

장바구니에 담은 도메인을 Checkout버튼을 눌러주면 아래 화면으로 넘어올거에요. Use DNS버튼을 눌러주신 후에 IP address 칸에 아까 애저 가상컴퓨터의 ip를 입력해주신 후 Continue를 눌러주세요.

Continue를 누르면 로그인 화면이 나와요. 구글이나 페이스북의 소셜 로그인을 이용할 수 있어요!

페이스북은 가끔 오류가 나기도 해요. 그럴때는 구글이나 MS Live계정으로 다시한번 시도해주세요.

로그인이 완료되면 아래와 같이 자신의 정보를 입력하는 부분이 나와요. 꼭 다 채울필요는 없어요!

주문 거래 동의 체크상자를 클릭한 후 계속 버튼을 누르면 주문이 완료된답니다! 좋아요!

Fabric3 설치하기

이제 여러분의 서버는 여러분이입력한이름.tk라는 인터넷 주소로 연결되었어요.

하지만 아직 여러분의 서버에는 아무것도 설치되어있지 않아요. 물론 장고도 설치되어있지 않아요.

이제 Fabric3이라는 멋진 자동화 도구를 통해 명령어 한 줄로(마치 startapp처럼) 진짜 서버에 배포하는 멋진 작업을 해볼거에요!

우선 여러분의 가상환경에 fabric3을 설치해줘야 해요. fabric3은 아래 명령어를 통해 설치할 수 있어요.

fabric이 아니라 fabric3입니다! 3을 빼먹지 마세요. 그냥 fabric은 파이썬2용이랍니다.

1
pip install fabric3

deploy.json 수정하기

이제 Fabfile for Django를 클릭해 압축파일을 받아 풀어주세요.

안에 deploy.jsonfabfile.py가 보일거에요. 이 두 파일을 여러분의 장고 폴더(manage.py파일이 있는 곳)안에 넣어주세요.

deploy.json파일 안에는 우리 서버의 정보를 적어넣을 수 있어요.

1
2
3
4
5
6
7
8
9
{
"REPO_URL":"깃헙Repo주소",
"PROJECT_NAME":"프로젝트폴더(settings.py가있는 폴더)의 이름(ex: mysite)",
"REMOTE_HOST":"여러분이 만든 도메인주소(ex: djangogirls-seoul-tutorial.tk )",
"REMOTE_USER":"django",
"STATIC_ROOT":"static",
"STATIC_URL":"static",
"MEDIA_ROOT":"media"
}

파일에 있는 REPO_URL, PROJECT_NAME, REMOTE_HOST 부분을 채워주세요. 나머지 값은 우리가 따라한 튜토리얼에서 이미 설정되어있어요.

모든 값은 “큰 따옴표” 안에 들어가야 한다는 것을 주의하세요!

Fabric으로 서버에 올리기

Fabric을 사용하기 위한 명령어는 fab이라는 명령어입니다. 이 fab뒤에 new_server, deploy, createsuperuser등을 덧붙여 실제로 원격 서버에 명령을 내리는거에요.

서버에 처음 올릴 때는 fab new_server 명령어를 이용하세요. 파이썬3 설치부터 Apache2설치와 mod_wsgi설치까지 완료해준답니다.

1
fab new_server

만약 여러분이 장고 소스를 수정(커밋&푸시)후 서버에 올리고 싶으시다면 fab deploy 명령어를 이용하세요. 장고 앱을 새로 실행해주고 manage.py migrate, manage.py collectstaticfiles등의 명령을 서버에 실행해 준답니다.

1
fab deploy

우리가 진행하는 튜토리얼에서는 슈퍼유저 만들기 항목이 있어요. 여러분의 컴퓨터에서는 manage.py createsuperuser를 통해 만들었지만 서버에 띄운 장고에 슈퍼유저를 만들어 주려면 fab create_superuser를 이용해주세요.

1
fab create_superuser

짜잔!

여러분은 이제 Azure에 올라간 진짜 웹 서비스 하나를 만들었어요! 이제 여러분은 장고로 웹 서비스를 만드는 것의 처음부터 끝까지를 모두 알게되었어요! 축하합니다 :D

배포한 Django 서비스 Exception Sentry로 받아보기

이번 포스팅은 wsgi기반으로 동작하는 django서비스를 대상으로 합니다.

Django 서비스를 실제 서버에 배포하면 보안을 위해 프로젝트 폴더의 settings.py파일 안의 DEBUG항목을 False로 두고 배포합니다. 이렇게 디버그모드를 끌 경우 장고에서 기본적인 보안을 제공해 줍니다. 그러나 만약 View나 Model에서 Exception이 발생했을 경우 클라이언트에 흰색의 500에러 화면만을 띄워줍니다.

이 경우 개발자에게도 장고의 에러 화면을 보여주지 않습니다. 따라서 Exception이 발생할 경우 개발자(혹은 운영자)에게 에러를 전송할 필요가 있습니다. wsgi 기반으로 서버를 구동할 경우 에러로그는 Apache2나 NginX등의 웹서버의 접근/에러로그가 있으며 Wsgi의 에러로그로 두가지가 있습니다.

장고서버의 경우에는 Wsgi의 에러로그에 로그를 쌓습니다. 그러나, Django 프로젝트에 LOGGERS 설정값을 추가해줘야 하며 에러 트래킹을 따로 설정해줘야 합니다.

이때 사용할 수 있는 것이 Sentry와 같은 서비스입니다.

이번 가이드는 Sentry for Django를 기반으로 진행합니다.

Sentry 설치하기

우선 raven을 설치해 줍니다.

raven은 Sentry를 위한 Python패키지입니다.

1
pip install raven --upgrade

Sentry settings.py에 설정하기

장고 프로젝트의 settings.py파일 안 INSTALLED_APPS에 아래 줄을 추가해줍니다.

1
2
3
4
INSTALLED_APPS = [
# 기존 앱 가장 아래에 추가해주세요.
'raven.contrib.django.raven_compat',
]

이제 Sentry용 환경변수를 추가해 줍시다. 아래 DSN_URL은 Sentry에 로그인 하신 후 Sentry for Django의 코드 부분을 복사하면 알 수 있습니다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
# settings.py 파일 import문 아래에 raven을 import해주세요.
import os
import raven

# import아래 환경변수를 설정해주세요. 이 URL은 위 Sentry for Django에서 바로 찾을 수 있습니다.
DSN_URL = 'https://sampleurl1234141534samplesample:somemoreurl12341235dfaetr@sentry.io/123456'

# 기타 설정들(생략...)

# settings.py 파일 가장 아래에 RAVEN_CONFIG를 추가해주세요.
RAVEN_CONFIG = {
'dsn': '{}'.format(DSN_URL), # DSN_URL을 위에 적어주셔야 동작합니다.
'release': raven.fetch_git_sha(BASE_DIR), # Django가 Git으로 관리되는 경우 자동으로 커밋 버전에 따른 트래킹을 해줍니다.
}

Sentry wsgi.py에 설정하기

이제 장고 프로젝트 폴더 안의 wsgi.py 파일을 아래와 같이 수정해봅시다.

1
2
3
4
5
6
7
8
9
10
import os

from django.core.wsgi import get_wsgi_application
from raven.contrib.django.raven_compat.middleware.wsgi import Sentry

# 이 부분은 여러분의 장고 프로젝트 이름을 쓰세요..
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "장고프로젝트이름.settings")

# get_wsgi_application을 Sentry()로 감싸주세요.
application = Sentry(get_wsgi_application())

자, 이제 Sentry 사용을 위한 기본적인 설정이 끝났습니다. 여러분의 서비스를 다시 원래 서버에 배포해보세요.

Exception이 발생하면..

이제 여러분이 잡아주지 않은 Exception이 발생할 경우 아래와 같이 이메일이 옵니다.

sentry django integrity error log mail

이메일의 Issue 링크를 클릭하면 아래와 같이 에러로그 페이지가 나옵니다.

Sentry django integrity error log web page

조금 더 알아보기

이번 포스팅에서는 장고의 Wsgi에서 발생하는 에러(Exception)을 Sentry 미들웨어를 통해 관리합니다. 그러나 유저에게 500페이지를 보여주는것은 여전합니다.

만약 여러분이 미리 잡아준 상황을 Sentry로 보내고 싶으시다면 Sentry를 logging와 함께 쓰기를 참고하세요.

Your browser is out-of-date!

Update your browser to view this website correctly. Update my browser now

×