qna blog using django - orm, 회원가입, 로그인/로그아웃

43
4주차: 회원가입과 로그인/로그아웃 1. 학습목표 1. ORM 다루기 Djang o 이용해 데이터베이스에 있는 데이터를 가져오고 저장하는 다뤄보도록 하겠습니다. 특히 번에는 회원가입 기능이므로 사용자로부터 회원 양식을 입력받아 저장하는 것을 다뤄볼 것입니다. Djang o 에서 기본적으로 제공하는 User 모델을 이용하겠습니다. 2. Form 다루기 데이터베이스에 저장하기 전에 먼저 데이터가 필요하겠지요? 그렇기 대문에 저번 시간에 배웠던 HTML태그를 이용해 사용자로부터 값을 입력받는 것을 Djang o 에서 처리해보도록 하겠습니다. 3. 로그인/로그아웃 이용하기 User Authentication기본 기능인 로그인과 로그아웃을 만들어보겠습니다. 이는 Djang o 에서 기본적 으로 제공하는 기능을 사용하겠습니다. 2. Preview

Upload: kwangyoun-jung

Post on 12-Aug-2015

121 views

Category:

Internet


9 download

TRANSCRIPT

Page 1: QnA blog using Django - ORM, 회원가입, 로그인/로그아웃

4주차: 회원가입과 로그인/로그아웃

1. 학습목표

1. ORM 다루기

Django를 이용해 데이터베이스에 있는 데이터를 가져오고 저장하는 등 다뤄보도록 하겠습니다. 특히 이번에는 회원가입 기능이므로 사용자로부터 회원 양식을 입력받아 저장하는 것을 다뤄볼 것입니다.Django에서 기본적으로 제공하는 User 모델을 이용하겠습니다.

2. Form 다루기

데이터베이스에 저장하기 전에 먼저 데이터가 필요하겠지요? 그렇기 대문에 저번 시간에 배웠던 HTML의폼 태그를 이용해 사용자로부터 값을 입력받는 것을 Django에서 처리해보도록 하겠습니다.

3. 로그인/로그아웃 이용하기

User Authentication의 기본 기능인 로그인과 로그아웃을 만들어보겠습니다. 이는 Django에서 기본적으로 제공하는 기능을 사용하겠습니다.

2. Preview

Page 2: QnA blog using Django - ORM, 회원가입, 로그인/로그아웃

[회원가입 화면]

Page 3: QnA blog using Django - ORM, 회원가입, 로그인/로그아웃

[로그인 화면]

Page 4: QnA blog using Django - ORM, 회원가입, 로그인/로그아웃

[로그아웃 화면]

3. ORM(Object Relational Mapping)

1. Database

Page 5: QnA blog using Django - ORM, 회원가입, 로그인/로그아웃

[DBMS-Database-Table-Column&Row]

DBMS

Relational Database, 즉 관계형 데이터베이스라고 합니다. 이런 데이터베이스는 위 그림에서와 같이DBMS라고 부르는 시스템에 의해 관리됩니다. 우리가 흔히(?) 보던 오라클, MSSQL, MySQL 등이 이에 속합니다. 단순히 데이터베이스만을 관리하는 것이 아니라 데이터베이스를 관리하는데 필요한 유저, 스키마 정보 등을 함께 관리해주는 종합 관리 툴입니다. 기업이 사용하는 DBMS도 있지만 개인이 사용하는DBMS도 있습니다. 대표적인 게 바로 Microsof t Access입니다.

우리가 개발할 때 사용하는 것은 SQLite3입니다. 이는 DBMS가 아니라 파일시스템입니다. 파일 하나로만 존재하거든요. Django로 프로젝트를 생성하면 프로젝트 루트 디렉토리(프로젝트 최상위 디렉토리)에db.sqlite3라는 파일이 보일겁니다. 이것이 SQLite3가 사용하는 파일입니다. 굉장히 단순한 데이터베이스이지만 개발할 떄는 매우 유용하게 사용합니다.

개발할 때는 이렇게 SQLite3로 사용하지만 나중에 서버에 업로드할 때는 Oracle 사의 MySQL이나Stanf ord 대학교에서 만든 PostgreSQL같은 DBMS를 사용할 것입니다.

그 외에도 많습니다. MySQL이 Oracle 사로 넘어간 이후 오픈소스에 제약이 생겨 그에 반하는 DBMS가 만들어졌는데 그것이 바로 MariaDB입니다. MySQL이나 MariaDB나 만든 개발자는 똑같아서 거의 같다고합니다. 참고로 Maria는 개발자 딸 이름이라고 하네요.

Page 6: QnA blog using Django - ORM, 회원가입, 로그인/로그아웃

또한, 관계형이 아닌 데이터베이스도 있습니다. 이를 NoSQL(Not Only SQL)이라고 부릅니다. 대표적으로 MongoDB가 있습니다.

Table

데이터베이스 안에 T able(or Relation)이 있습니다. 이는 데이터를 담는 그릇입니다. 이 테이블은 열(Column or Field or Attribute)과 행(Row or Record or T uple)로 구성되어있습니다. 수많은 행 중에단 하나의 행을 만들어주는 열이 있습니다. 이를 Primary Key라고 부릅니다.

Database

위에서 언급한 테이블을 모아놓은 것을 바로 데이터베이스라고 합니다.

Relational

그런데 데이터베이스이긴한데 관계형입니다. 데이터 간 특정 관계를 맺을 수 있다는 뜻입니다. 관계라는특성을 통해 데이터베이스의 테이블을 설계하는 작업을 모델링이라고 부릅니다. 즉, 현실에 있는 것을 추상화시키는 것을 말합니다.

간단한 예로써, 대한민국 국민인 정광윤 은 주민등록번호 라는 유일한 값으로 본인임을 증명할 수 있습니다. 이 번호를 가지고 보험을 가입할 수 있구요. 이럴 때 정부 데이터베이스 의 국민 테이블 의 ‘나’라는 레코드 에 나를 유일하게 해주는 값 즉, Primary Key인 주민등록번호를 통해 보험회사에 가입을 할 수 있습니다. 그 보험회사의 데이터베이스 는 정부 데이터베이스 를 참조하는 관계가 형성되는 것입니다. 참 쉽쥬!?ㅎㅎ

2. 데이터를 다루는 방법

Page 7: QnA blog using Django - ORM, 회원가입, 로그인/로그아웃

[어플리케이션이 데이터를 다루는 방법]

일반적으로 어플리케이션이 데이터를 참조하는 방법을 간단하게 도식화하면 위와 같습니다. 그 안에 데이터를 가리키는 Cursor라는 것도 필요하지만 그렇게 구체적으로 나가지는 않겠습니다.

우리가 데이터베이스의 데이터를 참조하기 위해선 다리(Connection) 를 놓고 그 위로SQL(Structured Query Language)이라고 부르는 데이터베이스가 이해할 수 있는 언어로 Query(질의) 를 해야합니다.

그런 질의문으로는 Select, Insert 같은 것이 있습니다.

이렇게 SQL 언어로 질의를 하면 데이터베이스는 그 질의를 이해하고 데이터를 어플리케이션에 반환해주는 것입니다.

즉 우리는 데이터베이스에 필요한 데이터를 가져오기 위해선 질의문(SQL) 을 알아야 합니다.

3. SQL을 몰라도 데이터를 알고 싶다!

그런데 말입니다. SQL을 몰라도 데이터를 참조하는 방법이 있습니다. 바로 ORM이라는 방법입니다. ORM이라는 것은 객체(Object or Instance)를 통해 데이터를 불러오거나 수정 또는 삽입하는 등 데이터를 처리할 수 있는 방법입니다. Django가 이 ORM을 사용하고 있습니다. 즉, 우리가 개발할 블로그에서는 SQL을몰라도 된다는 뜻입니다.

NOT E 물론 고도화된 서비스를 구축할 때 SQL을 사용할 떄도 있습니다. 따라서 더 전문적인 개발자가되기 위해선 SQL을 알아야 합니다.

Page 8: QnA blog using Django - ORM, 회원가입, 로그인/로그아웃

4. Django에서의 ORM

[Model Template View 소프트웨어 아키텍쳐 패턴]

그렇다면 Django에서 ORM은 언제 어떻게 작동되는 걸까요!? 아래에서 사용자가 페이지를 요청하는 순간부터 데이터베이스를 어떤 순서로 가져오는지 살펴보겠습니다.

1. 사용자가 페이지를 요청(HttpRequest)을 하면2. Django는 처음에 urls.py의 URL에 해당하는 View 함수를 연결해 줍니다.3. views.py에서 데이터를 필요로 할 때 데이터베이스에서 데이터를 찾아와야 하는데 Django는

models.py를 통해 데이터를 불러옵니다.4 . models.py에서 정의한 클래스를 통해 views.py에서 객체를 만들어 해당 객체를 통해

Database에 접근해 데이터를 가져옵니다.5. 가져온 데이터는 views.py에서 다시 템플릿 파일로 렌더링하여 사용자에게 보내집니다.

(HttpResponse)

Page 9: QnA blog using Django - ORM, 회원가입, 로그인/로그아웃

[Django에서의 ORM]

즉, Django에서는 모델( models.py )에 만든 클래스(Class)를 통해 객체(Object or Instance)를 만들고, 이 객체를 통해 Database에 접근하게 됩니다. 이 것을 도식화한 것이 위의 그림입니다.

5. SQL VS. ORM

항목 방법

SQL Select username f rom USER where id=1;

ORM User.objects.get(id=1).username

위는 id가 1인 사용자의 사용자 이름(username)을 가져오는 방법입니다. 그런데 이렇게면 보면ORM의 장점이 별로 없어 보이네요^^;; 하지만 위 예제보다 복잡도가 높은 어플리케이션에서 ORM으로 개발하면 코드를 좀 더 단순하고 깔끔하게 구현할 수 있습니다. 이에 생산성이 높아지며 테스트 또한 쉽게할 수 있습니다.

6. 클래스와 객체의 관계

위에서 설명했듯이 ORM은 객체를 통해 Data를 Handling하는 방법입니다. 그렇기 때문에 클래스와 객체의 관계를 좀 더 살펴볼 필요가 있습니다.

Page 10: QnA blog using Django - ORM, 회원가입, 로그인/로그아웃

[클래스와 객체]

위의 그림처럼 Django에서 미리 만든 Model을 상속받아 사용자 정의 모델을 만들고 이 클래스의 객체를통해 Database에 접근하게 됩니다. 이와 같이 객체는 클래스를 통해 만들어지게 됩니다.

이게 가능한 이유가 파이썬의 모든 것은 객체이기 때문입니다. 객체에는 속성(Properties)과 행동(Action)이 있습니다. 위 그림에서는 get이라는 행동(함수)을 통해 데이터베이스에서 id가 1인 데이터를 반환해 오는 것입니다.

여기서 객체는 클래스를 통해 만들어지는 구조를 보는 게 중요합니다. 그렇기 때문에 Django에서도Class를 먼저 만드는 작업을 할 것입니다.

정말 중요합니다. 객체(인스턴스라고도 부릅니다. 똑같은 뜻입니다.)는 클래스라는 틀을 통해 만들어지는 붕어빵과 같다고 보시면 됩니다.

Page 11: QnA blog using Django - ORM, 회원가입, 로그인/로그아웃

7. Model: ORM에서 테이블 정의하기

데이터베이스에서 테이블은 데이터를 담는 그릇입니다. 이 그릇의 구조를 RDBMS에서 만들수도 있고,SQL문을 통해 만들수도 있습니다. ORM에서는 데이터를 담는 그릇을 어떻게 정의할까요? 바로 위에서계속해서 언급했던 Model(models.py)입니다. 먼저 ORM이 아닐 때를 보겠습니다.

1) 다른 툴로 만들 때

[Table의 구조 설계]

위 그림과 같이 테이블 구조를 설계한다고 가정했을 때 DBMS로 직접 데이블을 만들 수 있습니다. 또한CREATE ...로 시작하는 SQL로 테이블을 만들기도 합니다. 이렇게 테이블을 설계하고 만들 때 파이썬과 같은 프로그래밍 언어로 처리하는 것이 아니라 데이터베이스를 직접 Handling 합니다.

그리고 데이터를 담으면 아래와 같은 모습이 됩니다.

Page 12: QnA blog using Django - ORM, 회원가입, 로그인/로그아웃

[Table의 데이터를 GUI 형태로 본 모습]

2) ORM으로 만들 때

[ORM 방식으로 구조 설계]

하지만 ORM 방식은 DBMS나 SQL과는 상관이 없습니다. 객체로 데이터베이스에 접근하는 방식이기 때문이지요. 그렇기 때문에 파이썬과 같은 프로그래밍 언어로 클래스를 만들어주면 됩니다. 위 그림과 같이클래스를 선언하고 아래에 속성으로 필드를 정의해주는 것입니다.

이렇게 Django는 데이터베이스의 테이블에 해당하는 클래스를 Model(models.py) 에서 정의합니

Page 13: QnA blog using Django - ORM, 회원가입, 로그인/로그아웃

다. 이것이 바로 MTV Pattern의 Model 부분인 것입니다.

8. Model Manager in Django

하나면 더 보고 가겠습니다. 이제 우리는 models.py에서 만들어진 클래스를 통해 객체를 만들어 데이터베이스에 접근한다는 것을 알았습니다. 이렇게 끝나는 줄 알았는데, Model Manager라는 것은 무엇일까요?

특정 모델에 있는 모든 데이터를 가져올 때는 아래와 같이 작성합니다.

클래스.objects.all()

특정 모델에 id가 1인 값을 가져올 때는 아래와 같이 작성합니다.

클래스.objects.get(id=1)

위 예제를 보면 알겠지만 저는 만든 적도 없는데 클래스 뒤에 objects가 붙는 걸 볼 수 있습니다. 이것이 Django의 Model manager입니다.

Django의 공식 문서에는 아래와 같이 설명하고 있습니다.

A Manager is the interf ace through which database query operations are provided toDjango models. At least one Manager exists f or every model in a Django application. Bydef ault, Django adds a Manager with the name objects to every Django model class.

위 설명처럼 objects라는 이름의 Model manager는 데이터베이스와 Django의 model 사이의 Queryoperation(질의 연산)이 일어나는 인터페이스역할을 해줍니다.

이제 앞으로 클래스.objects로 시작하는 것을 많이 보게 될 것입니다. 이것이 데이터베이스와의 인터페이스 역할을 하기 때문에 Query operation 즉, 데이터를 찾고 입력하는 등의 핸들링을 할 수 있는 것입니다. 특히 다수의 데이터를 가져오는 함수를 사용할 때 반환되는 객체를 QuerySet이라고 부릅니다. 이것은 나중에 또 보도록 하겠습니다.

아래 공식 문서를 링크할테니 참고해서 보시면 더 좋을 것 같습니다.

1. Manager 클래스 동작 원리2. QuerySet API

4. Django에서 데이터 다루기위에서 우리는 Django를 이용해 데이터베이스의 데이터에 어떻게 접근하는지 열심히 배웠습니다. 이제

Page 14: QnA blog using Django - ORM, 회원가입, 로그인/로그아웃

는 실제로 실습을 해보겠습니다. 기본적으로 데이터를 생성하고 읽고 갱신하고 삭제하는 것을 이르러CRUD라고 부릅니다.

이름 조작 SQL

Create 생성 INSERT

Read 읽기 SELECT

Update 갱신 UPDATE

Delete 삭제 DELETE

위 CRUD를 실습해보겠습니다.

1. 준비작업

데이터를 다루기 위해서는 당연히 데이터베이스가 먼저 있어야 합니다. 데이터베이스를 만드는 작업을먼저 해보겠습니다.

저희가 만든 현재의 프로젝트는 데이터베이스에 테이블이 있지 않습니다. 만든 적이 없거든요. 아래 명령어를 통해서 Django에서 기본적으로 제공하는 모델을 저희 데이터베이스에 적용해 보도록 하겠습니다.

1) makemigrations

아래와 같이 적고 실행해보겠습니다.

$ python manage.py makemigrations

이는 프로젝트에서 새로 생성되었거나 변경된 모델 구조를 파악하여(Detect) Database에 적용할 수 있도록 실행 스크립트를 만드는 작업입니다. 이 작업을 했다고 Database에 적용이 되는 것은 절대 아닙니다. 말 그대로 실행할 수 있는 스크립트 파일만 만들어주는 것입니다.

여기서 모델은 App안에만 있습니다. 그렇기 때문에 우리가 만든 qna 디렉토리 안을 보면 migrations라는 디렉토리가 있는 것을 확인할 수 있습니다. 이 디렉토리가 makemigrations를 실행해서 나온 스크립트가 저장되는 곳입니다.

2) migrate

다음으로 아래와 같이 적고 실행해보겠습니다.

$ python manage.py migrate

Page 15: QnA blog using Django - ORM, 회원가입, 로그인/로그아웃

[Migrate를 실행한 화면]

migrate라는 것은 이 파일에 Django에서 사용할 테이블을 만드는 실제 작업이 이루어지는 명령입니다. 즉, 앞에서 만든 스크립트 파일을 실행해서 Database에 적용한다는 것입니다.

기본적으로 모델의 구조가 바뀌게 되면 위 작업은 꼭 수행해야합니다. 그래야 Database에 적용되기 때문입니다.

1. python manage.py makemigrations 2. python manage.py migrate

이렇게 실행하고 나면 프로젝트 루트 디렉토리에 db.sqlite3 파일을 확인할 수 있습니다. 이 파일이바로 우리가 사용하는 SQLite3라는 데이터베이스 파일입니다.

2. Django Shell

이제 Django shell에서 직접 컨트롤 해보겠습니다. Django shell이란 것은 Django 패키지를 사용할 수있는 인터프리터 환경이라고 보시면 됩니다. 아래와 같이 manage.py가 있는 디렉토리 즉, 저희가 앞에서 만든 studybee라는 프로젝트 루트 디렉토리로 가서 실행해보겠습니다.

$ python manage.py shell

Page 16: QnA blog using Django - ORM, 회원가입, 로그인/로그아웃

[Django Shell]

3. Django의 User 모델 사용하기

여기서 우리는 Django에서 기본적으로 제공하는 User 모델을 사용해 데이터를 컨트롤 해보겠습니다.

1) 지금부터 User 모델을 사용하겠다! 라고 선언하기

Django shell에서 아래와 같이 입력하여 Django에서 제공하는 User 모델을 사용하겠다고 선언해 주겠습니다.

from django.contrib.auth.models import User

~에서 라는 뜻이지요. 여기에선 django 패키지 안의 contrib 패키지 안의 auth 패키지 안의 models 라는모듈안의 User라는 클래스를 이제부터 사용하겠다! 라는 뜻입니다.

NOT E 파이썬에서는 디렉토리가 패키지입니다. 파이썬에서는 파일이 모듈입니다. 파이썬에서는 관례상 대문자로 시작하는 객체는 클래스입니다.

주의사항 만약에 위와 같이 선언한 부분 위에서 User 클래스를 사용한다면? 파이썬은 순서대로 실행을 하기 때문에 위에서 사용한다면 에러가 납니다. 반드시 위와 같이 선언한 아래부분부터 User 클래스를 사용해야 합니다.

Page 17: QnA blog using Django - ORM, 회원가입, 로그인/로그아웃

2) User 모델은 어떤 구조로 되어있을까?

아래와 같이 작성해서 실행해볼까요?

User._meta.fields

파이썬에는 메타 클래스라는 개념이 있습니다. 이는 어려운 내용이므로 이 부분에서는 자세히 다루지는않고 간단히 Data about data 라고만 알고 지금은 넘어가도록 하고, 아래 공식 문서를 참고하시기 바랍니다.

_meta 관련 공식 문서 (1.7 버전에서는 없으나 1.8버전의 공식 문서부터 _meta 정보가 포함되어있음)

실행결과는 아래와 같습니다.

>>> User._meta.fields[<django.db.models.fields.AutoField: id>,<django.db.models.fields.CharField: password>,<django.db.models.fields.DateTimeField: last_login>,<django.db.models.fields.BooleanField: is_superuser>,<django.db.models.fields.CharField: username>,<django.db.models.fields.CharField: first_name>,<django.db.models.fields.CharField: last_name>,<django.db.models.fields.EmailField: email>,<django.db.models.fields.BooleanField: is_staff>,<django.db.models.fields.BooleanField: is_active>,<django.db.models.fields.DateTimeField: date_joined>]

Schema

User Model을 구성해 놓은 소스를 찾아보면 Schema는 아래와 같이 되어있다는 것을 알 수 있습니다.

필드명 Django 필드타입 DB 필드타입 제약조건

id AutoField Integer Primary Key

username CharField varchar(30) Unique

password CharField varchar(128)

last_login DateTimeField datetime

f irst_name CharField varchar(30)

last_name CharField varchar(30)

Page 18: QnA blog using Django - ORM, 회원가입, 로그인/로그아웃

email EmailField varchar(75)

is_staf f BooleanField bool

is_active BooleanField bool

date_joined DateTimeField datetime

is_superuser BooleanField bool

필드명 Django 필드타입 DB 필드타입 제약조건

Source 검색

소스를 열어보는 행동은 프로그래밍 실력을 높이는데 매우 중요합니다. 다른 개발자가 만든 좋은 소스를보면서 익힐 수 있기 때문이지요.

django.contrib.auth.models.py에 class User를 검색해 보겠습니다.

소스를 보면 클래스 상속체계가 아래와 같이 구성되어있다는 걸 알 수 있습니다.

어렵지요!? 그냥 이렇게 만들어져있는데 상속되어오면서 중간 중간 속성과 메소드가 설정되어있다는 것만 봐도 괜찮습니다.

4. Create

User 모델에 새로운 사용자 데이터를 입력해 보겠습니다. 클래스로부터 객체를 만드는 방법을 기억하시죠?

models.Model

class AbstractBaseUser

class AbstractUser

class User

Page 19: QnA blog using Django - ORM, 회원가입, 로그인/로그아웃

객체명 = 클래스명(인자=인자값)

위 방법대로 객체를 생성하면 클래스에 있던 속성과 메소드를 그대로 물려받은 붕어빵이 생기게 되는 것입니다. 위 방법으로 사용자를 추가해보겠습니다.

user1 = User(username='test1', email='[email protected]')user1.set_password('test')user1.save()

user2 = User(username='test2', email='[email protected]')user2.set_password('test')user2.save()

1) user1 = User(username=’test1’, …)

User라는 클래스를 통해서 user1이라는 객체를 만들었습니다. username과 email이라는 속성에 특정값이 입력된 객체가 생성된 것입니다.

2) user1.set_password(‘test’)

패스워드를 세팅하는 부분입니다. 클래스로부터 만들어진 객체 user1은 User 클래스가 가지고 있던 메소드와 속성을 사용할 수 있습니다. 그 중에 set_password()라는 메소드를 사용하여 패스워드 값을 세팅한것입니다.

그런데 이상합니다. 위에서 user1 이라는 객체를 만들 때 패스워드를 입력하고 만들면 덜 수고스러웠을텐데요. 그쵸?!

구지 set_password()라는 메소드를 사용하는 이유는 패스워드는 암호화되어 Database에 저장처리할필요가 있기 때문입니다. 이 set_password()라는 메소드가 사용자에게 입력받은 스트링값을 암호화 처리해주는 역할을 해주기 떄문에 이 메소드를 사용하는 것입니다.

더 정확히 말하면 그냥 암호화가 아니고 Hash 암호화입니다. 이는 위키피디아 문서를 참고하시기 바랍니다.

3) user1.save()

이렇게 user1 이라는 객체에 username, password 를 저장하였고 이제 이 것을 Database에 저장해야 합니다. 이는 save()라는 메소드를 통해서 하게 됩니다.

이제 데이터가 제대로 들어갔는지는 아래에서 확인해보겠습니다.

5. Read

Page 20: QnA blog using Django - ORM, 회원가입, 로그인/로그아웃

1) 데이터 불러오기

all()

아래와 같이 입력하여 User 모델에 있는 모든 데이터를 불러와 보겠습니다.

User.objects.all()

f irst()

User 모델의 첫 번째 데이터만 가져옵니다.

User.objects.first()

last()

User 모델의 마지막 데이터만 가져옵니다.

User.objects.last()

order_ by()

User 모델을 아래와 같이 정렬시켜 데이터를 가져와 보겠습니다. Ascending 즉, 오름차순이 기본값입니다.

User.objects.order_by('username')

아래와 같이 ‘-‘을 입력하면 Descending 즉, 내림차순이 됩니다.

User.objects.order_by('-username')

여러개를 동시에 정렬처리시킬 수도 있습니다.

User.objects.order_by('-date_joined', 'username')

values()

User.objects.all()

Page 21: QnA blog using Django - ORM, 회원가입, 로그인/로그아웃

위와 같이 실행했을 떄는 테이블의 Row에 해당하는 데이터가 나오는 것이 아니고, 하나의 객체가 나옵니다. 각 객체의 데이터가 무엇인지 알아보기 위해서는 아래와 같이 values()함수를 사용합니다. 이 때반환값은 {key:value} 의 형태를 띄는 사전 객체라는 것을 유의하시기 바랍니다.

User.objects.values()

특정 컬럼의 값만 알고 싶다면 아래와 같이 인자값으로 필드명을 넘겨줍니다.

User.objects.values('username')

values_ list()

values()가 사전 객체로 보여줬다며, values_list() 함수는 key가 빠진 value값만 보여줍니다.

User.objects.values_list('username')

NOT E values()와 values_list() 함수는 QuerySet일 때만 가능합니다.

2) 조건 검색

아래와 같이 get과 f ilter를 통해 조건 검색을 할 수 있습니다.

User.objects.get(username='test')

User.objects.filter(email='[email protected]')

여러 조건 중에 아래와 같이 username 필드에서 ‘test’로 시작하는 데이터만 가져올 수 있도록 처리해줄수 있습니다.

필드__옵션

User.objects.filter(username__startswith='test')

NOT E get() 함수를 사용할 경우 반환값은 조건에 해당하는 객체가 됩니다. 그러나 filter() 함수를 사용하여 나온 반환값은 QuerySet 객체가 됩니다. 질의(Query)를 해 여러 개의(Set) 데이터가 나올 수 있기 때문입니다. 그래서 get()함수의 반환값을 잘 보면 <...>이렇게 생겼고

Page 22: QnA blog using Django - ORM, 회원가입, 로그인/로그아웃

filter()의 반환값은 [<...>,] 이렇게 생겼습니다. 즉, 리스트 안에 객체를 담은 것입니다.

3) Field Lookups

필드__옵션

위에서 실습해 보았던 filter(username__startswith)의 Double underscore(__) 오른쪽을 FieldLookups라고 부릅니다. 굉장히 다양한데 아래를 참고하시기 바랍니다. 이는 공식 문서에서 일부 가져온내용입니다.

Name Desc. Example

exact Case-sensitive exactmatch

Entry.objects.get(id__exact=14 )

iexact Case-insensitiveexact match

Blog.objects.get(name__iexact=’beatles blog’)

contains Case-sensitivecontainment test

Entry.objects.get(headline__contains=’Lennon’)

icontains Case-insensitivecontainment test

Entry.objects.get(headline__icontains=’Lennon’)

in In a g iven list, or 조건 Entry.objects.f ilter(id__in=[1, 3, 4 ])

gt Greater than Entry.objects.f ilter(id__gt=4 )

gte Greater than or equalto

lt Less than

lte Less than or equal to

startswith Case-sensitivestarts-with

User.objects.f ilter(username__startswith=’test’)

istartswith Case-insensitivestarts-with

User.objects.f ilter(username__istartswith=’test’)

endswith Case-sensitive ends-with

iendswith Case-insensitiveends-with

Page 23: QnA blog using Django - ORM, 회원가입, 로그인/로그아웃

range Between dates Entry.objects.f ilter(pub_date__range=(datetime.date(2015,1,1), datetime.date(2015,1,31))

isnull Takes either T/F User.objects.f ilter(f irst_name__isnull=True)

Name Desc. Example

6. Update

값을 수정할 때 사용합니다. update() 함수는 QuerySet에 있는 함수이며 save()가 함께 있습니다.

User.objects.filter(username='test').update(email='[email protected]')

User.objects.all().update(email='[email protected]')

User.objects.filter(username__startswith='test').update(email='[email protected]')

그렇다면 QuerySet이 아니라 get() 함수를 이용해 객체로 반환된 것에는 어떻게 수정해야할까요?

user1 = User.objects.get(pk=1)user1.first_name='Chris'user1.save()

위에서 두 번째 명령처럼 값을 치환해주고 꼭 save() 를 실행해줘야 저장이 됩니다.

7. Delete

지우는 것은 간단하게 아래와 같이 사용합니다.

User.objects.get(username='test2').delete()

User.objects.filter(id__range=(10, 20)).delete()

만약 유저의 탈퇴 처리 기능을 만들고 싶다면 delete() 함수를 사용하면 되겠지요.

Page 24: QnA blog using Django - ORM, 회원가입, 로그인/로그아웃

8. 그 외

위에서 언급한 것 외에도 많은 것들이 있습니다. 대표적으로 아래의 것은 자주 사용하는 메소드이니 숙지하고 있으면 좋을 것 같습니다.

1) get_or_create()

obj, created = User.objects.get_or_create(first_name='John', last_name='Lennon', defaults={'username': 'Legend')})

first_name이 John 이면서, last_name이 Lennon인 데이터가 있으면 가져오고(get) 없으면defaults={ ... } 값으로 생성(create)하는 함수입니다. 이 함수를 사용하지 않으면 try ...except ...를 하거나 비교문을 이용해 처리를 해야합니다. 그러나 get_or_create() 함수를 이용하면 간편하게 가져오거나 생성할 수 있겠지요!?

get 하거나 create 한 객체가 obj 에 할당되고 만약 create 하면 created 라는 변수에는 True가 들어가고 그렇지 않으면 False가 할당됩니다.

2) update_or_create()

obj, created = User.objects.update_or_create(first_name='John', last_name='Lennon', defaults={'email':'[email protected]'})

get_or_create() 함수와 비슷합니다. 만약 first_name이 John 이면서, last_name이Lennon인 데이터가 있으면 defaults={ ... } 에 있는 내용으로 update 하고 없으면 생성해줍니다.

3) count()

데이터의 갯수를 셀 수 있습니다.

User.objects.count()

4) exists()

모델에 데이터가 있는 지 유무를 판단할 수 있습니다. 반환값은 True or False 입니다.

User.objects.exists()

Page 25: QnA blog using Django - ORM, 회원가입, 로그인/로그아웃

5. 회원가입먼 길오느라 수고하셨습니다. 자, 이제부터는 본격적으로 회원가입 페이지를 만들어 보겠습니다.

1. Model

1) Django의 User 모델 이용하기

저희는 블로그를 만들 때 Django에서 이미 만들어 놓은 User를 사용하겠습니다. 따라서 특별히 어떤 조치를 해야할 것은 없습니다. 이렇게 개발의 시간이 단축되는 것입니다. User 모델의 경로만 다시 한 번 확인해보도록 하겠습니다.

from django.contrib.auth.models import User

2. Template

템플릿 파일에서는 사용자가 회원 가입할 때 필요한 정보를 입력할 수 있는 화면을 만들 것입니다. 여기에서는 아래 3가지를 보도록 하겠습니다.

1. 사용자에게 값을 입력받는 Form 태그2. Form 태그를 자동생성해 주는 Django의 Form 기능3. Django가 템플릿을 처리하는 Django Template Engine

1) 환경 설정

우선 템플릿을 사용하기 위해선 환경 설정을 해줘야 합니다.

T emplate이 저장될 디렉토리 만들기

Page 26: QnA blog using Django - ORM, 회원가입, 로그인/로그아웃

[프로젝트 전체 구조]

먼저 우리가 만들 signup.html파일이 저장될 디렉토리를 만들겠습니다. 프로젝트 최상위 경로에서

Page 27: QnA blog using Django - ORM, 회원가입, 로그인/로그아웃

아래오 같이 실행합니다.

$ mkdir templates$ cd templates$ mkdir registration

디렉토리 이름은 아무거나 입력해도 상관없지만 여기서는 templates라고 하겠습니다. 그리고 그 하위에 registration이라는 디렉토리를 만들어서 회원가입과 로그인 관련 템플릿은 이 곳에 넣어두겠습니다.

T emplate을 사용하겠다고 세팅하기

이제 template을 사용하겠다고 세팅을 해줘야 합니다. settings.py에 아래와 같이 입력합니다.

# Build paths inside the project like this: os.path.join(BASE_DIR, ...)import osBASE_DIR = os.path.dirname(os.path.dirname(__file__))TEMPLATE_DIRS = (os.path.join(BASE_DIR, 'templates'),) # 추가된 부분

위에 작성한 것처럼 TEMPLATE_DIRS라는 변수에 값을 넣어주는 것입니다. 문서 어디에 넣어도 상관없습니다. 단, TEMPLATE_DIRS에 BASE_DIR이라는 변수를 사용하고 있기 때문에 BASE_DIR이라는변수 위에 입력해서는 안됩니다. 그래서 일부러 BASE_DIR 변수 바로 아래 부분에 입력해 놓았습니다.

(os.path.join(BASE_DIR, 'templates'),)의 의미는 BASE_DIR이라는 프로젝트 최상위 경로가 들어가 있는 변수에 우리가 새로 만든 디렉토리인 templates를 join (조인) 하겠다는 뜻입니다. 즉우리가 만든 디렉토리 경로를 TEMPLATE_DIRS에 할당해준 것뿐입니다.

T emplate 파일에서 request 객체를 사용하겠다고 세팅하기

settings.py파일에 아래 부분을 아무곳에나 입력해 줍니다.

TEMPLATE_CONTEXT_PROCESSORS = ( "django.contrib.auth.context_processors.auth", "django.core.context_processors.debug", "django.core.context_processors.i18n", "django.core.context_processors.media", "django.core.context_processors.static", "django.core.context_processors.tz", "django.contrib.messages.context_processors.messages", 'django.core.context_processors.request',)

이 부분은 Template Context Processor 즉, 템플릿 컨텍스트 처리기라고 합니다. 템플릿 파일에 특정값(Django는 Context라고 부릅니다.)을 보낼 때 일부 특수한 처리가 필요한 게 있습니다. 바로 그런 부분을누가하는지 입력한 것입니다. 이는 외울 필요가 전~혀~ 없습니다. 그냥 복사 붙여넣기 하시면 됩니다. 심

Page 28: QnA blog using Django - ORM, 회원가입, 로그인/로그아웃

지어 1.8 버전부터는 자동으로 세팅되어 나옵니다.

자세한 것은 공식 문서를 참고하시기 바랍니다.

2) Form 태그

[회원가입 화면]

웹에서는 사용자에게 특정 값을 입력받아 오기 위해서는 HTML의 Form 태그를 반드시 사용해야 합니다.우리말로 바꿔보면 ‘양식’이니, 맞는 말인 것 같습니다.

그리고 사용자에게 값을 입력받은 후 그 값이 요구한대로 적었는지 검사하는 검증 절차(Validation)를 거

Page 29: QnA blog using Django - ORM, 회원가입, 로그인/로그아웃

쳐야 합니다. 예를 들어 email은 email 형식대로 작성했는지를 검사하는 것을 말하는 것입니다.

Django에서는 이렇게 많이 쓰이는 Form 태그와 검증 절차를 이미 만들어 놓았습니다.

3) Django의 Form 이용해 만들기

f rom django import f orms

[Model Template View 소프트웨어 아키텍쳐 패턴]

우리는 Django에 있는 Form 기능을 이제부터 사용할 것입니다. Django에서 제공하는 것은 크게 두 가지가 있습니다.

1. django.f orms.Form 2. django.f orms.ModelForm

1번, 2번 모두 Form 태그를 만들어주고 Validation 기능도 있습니다. 하지만 2번의 경우는 조금 다른 게있습니다.

사용자에게 입력한 값이 결국 데이터베이스에 저장되는 경우라면 2번을 사용하면 편리합니다. 해당Form에 Model을 연결시켜놓은게 ModelForm이기 때문입니다. 우리는 사용자에게 사용자 정보를 입력받아 User 모델에게 바로 저장하는 것이기 때문에 ModelForm을 사용하도록 하겠습니다.

Page 30: QnA blog using Django - ORM, 회원가입, 로그인/로그아웃

UserCreationForm

그런데 Django는 회원가입 폼도 미리 만들어놨습니다!!! 감사한 일이지요? 위치는 아래와 같습니다.

from django.contrib.auth.forms import UserCreationForm

UserCreationForm 을 이용해서 만들면 아래와 같이 나옵니다.

[UserCreationForm]

미리 만들어놓은 폼에는 Username, Password, Password conf irmation 이렇게 세 가지만 입력하게 되어있습니다. 하지만 우리는 이메일을 하나 더 받을 생각입니다. 이번엔 UserCreationForm 으로만 작성하고 다음 시간에 추가해보도록 하겠습니다.

4) html 만들기

signup.html

자, 지금까지 우리가 만들진 않았지만 Django에서 만들어놓은 것, 아래와 같은 두 가지를 이용할 준비(?)가 다 되었습니다.

1. User 모델2. UserCreationForm

이제는 템플릿 파일을 직접 만들어 보겠습니다. 아래와 같이 만들겠습니다.

<html><body>

<!-- Sign Up Form --> <form id="signup" method="post" action="{% url 'signup' %}">

Page 31: QnA blog using Django - ORM, 회원가입, 로그인/로그아웃

{% csrf_token %} {{ userform.as_p }} </form>

</body></html>

이렇게 만든 signup.html을 프로젝트 최상위 디렉토리의 templates > registration 디렉토리에 저장하겠습니다.

{% url ‘signup’ %}

urls.py에서 name이 signup으로 된 url pattern으로 이동하라는 의미입니다. 이는 Django templatelanguage이며 url은 함수입니다.

{% csrf _ token %}

Cross-Site Request Forgery라는 공격 방법을 막을 수 있도록 Django에서 미리 기능을 제공합니다. 사용자가 값을 입력해주는 Form 태그 시작부분에 무조건 써줘야 에러가 나지 않습니다.

{{ userf orm.as_ p }}

views.py에서 UserCreationForm 을 이용해 userform 이라는 객체를 만들 예정입니다. 그리고이 객체를 그대로 템플릿 파일에 보내줄건데요. 그렇게 되면 UserCreationForm 기능을 그대로 사용할 수 있게 됩니다.

{{ … }}

{{ ... }} 이라는 것은 Django template language에서 템플릿 변수를 말합니다. as_p라는 함수는UserCreationForm 에 있던 사용자가 입력한 값을 HTML로 변환해서 뿌려주는데 매 단락마다 <p> 태그를 적용시켜 줍니다.

as_p 외에도 몇 개 더있습니다.

as_ul : <ul> 태그 적용 as_table : <td> 태그 적용

signup_ ok.html

이번엔 회원가입을 정상적으로 완료했을 때의 페이지를 만들겠습니다. 아래와 같습니다.

Page 32: QnA blog using Django - ORM, 회원가입, 로그인/로그아웃

[회원 가입을 완료한 후의 페이지]

이 페이지는 로그인할 수 있도록 링크만 했을 뿐 사용자에게 어떤 값을 입력받는 등의 기능은 없습니다.

예쁘게 옷을 덧입는 것은 다음 시간에 차차 하도록 하고 오늘은 기능 구현에만 집중하겠습니다. 아래와 같이 signup_ok.html파일을 만들도록 하겠습니다. 이 파일 역시 templates > registration 디렉토리에 저장하겠습니다.

<center>Successfully signed up. Do you want to log in?<br><a href="{% url 'login_url' %}">Log In</a></center>

Page 33: QnA blog using Django - ORM, 회원가입, 로그인/로그아웃

3. View

1) 회원 가입 Flow Chart

회원 가입의 Flow Chart는 위와 같습니다. 이 부분을 그대로 프래그래밍하면 아래와 같습니다. 이는qna의 views.py에 입력합니다.

2) 소스

Start

회원가입 링크 클릭 (method='GET")

회원가입 페이지 접속 (/signup/)

Is it POST?

DB에 저장

Redirect to signup_ok.html

End

회원정보 작성 후 저장 버튼 클릭 (method='POST")

yes

no

Page 34: QnA blog using Django - ORM, 회원가입, 로그인/로그아웃

from django.http import HttpResponseRedirectfrom django.core.urlresolvers import reversefrom django.contrib.auth.forms import UserCreationForm

def signup(request): """signup to register users """ if request.method == "POST": userform = UserCreationForm(request.POST) if userform.is_valid(): userform.save()

return HttpResponseRedirect( reverse("signup_ok") ) elif request.method == "GET": userform = UserCreationForm()

return render(request, "registration/signup.html", { "userform": userform, })

request.method

전체적인 구조를 보면 먼저

request.method가 1. GET 2. POST

일 떄 두 가지 방식으로 나누어져 있는 것을 볼 수 있습니다.

이는 사용자 요청(request) 방식(method)이 GET인지 POST인지에 따라 내용이 달라지기 떄문입니다.

POST 방식일 때만 사용자가 입력한 값이 들어가 있기 때문에 Validation과 Save를 해줘야 하고, GET일때에는 사용자 입력 값이 없으므로 아무런 처리를 해주지 않아도 되는 것입니다.

GET 방식일 때

먼저 GET방식일 때를 보겠습니다. 아무런 입력값없이 요청된 것이기 때문에 아무것도 입력하지 않은UserCreationForm 의 객체를 만들어주기만 하면 됩니다.

그리고 이렇게 만든 객체를 뒤에서 템플릿에다 보내기만 하면 끝납니다.

elif request.method == "GET": # 만약 GET방식이라면 # UserCreationForm 클래스를 이용해 userform이라는 객체를 만들어라

Page 35: QnA blog using Django - ORM, 회원가입, 로그인/로그아웃

userform = UserCreationForm()

return render(request, "registration/signup.html", { "userform": userform, })

그리고 render 라는 함수를 이용해서 두 번째 인가값인 템플릿 파일에 세 번째 인값과 함께 렌더링해서보내주게 됩니다. 이 세 번째 인자값에 바로 우리가 위에서 만든 userf orm 객체를 사전 객체로 보내줍니다.

POST 방식일 때

if request.method == "POST": userform = UserCreationForm(request.POST) if userform.is_valid(): userform.save()

return HttpResponseRedirect( reverse("signup_ok") )

UserCreationForm 클래스로부터 userf orm이라는 객체를 만들자!

먼저 GET 방식일 때와 마찬가지로 UserCreationForm 클래스로부터 userform 이라는 이름으로 객체를 하나 만들어 줍니다. 이 때 중요한 것이 POST방식은 사용자가 값을 입력했을 경우이므로 입력한 값(request.POST)을 UserCreationForm 클래스에 넣어주고 객체를 만든다는 것입니다.

사용자가 입력한 값은 request.POST안에 있다!

사용자가 입력한 값은 request.POST 에 사전 객체 형태로 들어가 있습니다.

is_ valid() 함수를 통해 Validation하자!

그런 후 매우 중요한 부분이 나옵니다. 바로 is_valid() 함수입니다. 이는 Django의 Form에서 제공해주는 유용한 기능입니다. 바로 사용자가 입력한 값을 Validation 해주는 함수입니다. 이 때 Validation에통과하면 True값을 반환하고 실패하면 왜 실패했는지 에러 메시지를 홈페이지 화면에 보여줍니다.

데이터베이스에 저장하자!

이렇게 통과한 객체는 userform.save() 를 통해 데이터베이스에 저장하게 됩니다.UserCreationForm 이라는 클래스에 이미 User 모델을 사용하겠다고 지정되어 있기 때문에 가능한 것입니다.

저장 완료했으니 페이지 이동!

저장한 후 아래와 같이 페이지를 Redirect로 이동해 해줍니다. 이 때 우리는 HttpResponseRedirect라는 클래스를 이용해서 이동시켜줍니다. 그런데 reverse라는 함수를 이용해서 이동하게 될 URL주소를 입

Page 36: QnA blog using Django - ORM, 회원가입, 로그인/로그아웃

력해줍니다. 이 함수는 우리가 urls.py에서 name으로 지정했던 URL을 의미합니다.

return HttpResponseRedirect( reverse("signup_ok") )

우리가 사용할 객체를 잊지말고 선언하자!

우리는 위에서 UserCreationForm , HttpResponseRedirect , reverse라는 것을 사용했습니다.이미 만들어져 있는 어떤 객체를 사용하기 위해서 이렇게 먼저 선언을 해주는 작업이 필요합니다. 꼭 잊지말고 해줘야합니다.

from django.http import HttpResponseRedirectfrom django.core.urlresolvers import reversefrom django.contrib.auth.forms import UserCreationForm

4. URL

1) 회원가입 경로 설정

지금까지 우리는 아래의 것을 준비하였습니다.

1. User Model2. UserCreationForm3. 템플릿 파일4 . View

자, 이제는 마지막 하나가 남았습니다. 바로 사용자가 요청한 경로를 인식해 함수로 연결시켜주는urls.py입니다. 프로젝트와 이름이 같은 시작 패키지 디렉토리안에 urls.py에 아래와 같이 작성하도록 하겠습니다.

urlpatterns = patterns('', # 중략, url(r'̂ signup/$', 'qna.views.signup', name='signup'),)

위와 같이 사용자가 http://hostname/signup 경로로 접속했을 때 바로 옆에 인자값인 qna 앱의views 모듈의 방금 위에서 만든 signup 함수로 연결해주는 역할을 합니다.

2) 회원가입 완료 후 페이지 경로 설정

Page 37: QnA blog using Django - ORM, 회원가입, 로그인/로그아웃

하나 더 추가하겠습니다. 회원가입을 정상적으로 완료했을 때의 페이지를 보여줄 수 있도록 URL 패턴을아래와 같이 설정하겠습니다.

from django.views.generic import TemplateView

urlpatterns = patterns('', # 중략, url(r'̂ signup_ok/$', TemplateView.as_view( template_name='registration/signup_ok.html' ), name='signup_ok'),)

T emplateView.as_ view()

동적인 기능이 있는 페이지가 아닌 페이지를 Static page라고 부릅니다. 말그대로 정적인 페이지이지요.이런 페이지는 아무런 기능도 없는데 구지 함수로 이동했다가 템플릿으로 갈 필요가 없습니다. 그래서Django는 이럴 때를 대비해 만들어 놓은 기능이 있습니다. 바로 TemplateView.as_view()라는 것인데요. 이를 Generic View라고 합니다.

어려운 부분은 아니고 동적인 페이지가 아닌 페이지를 보여줄 때 쓰는구나 라고 알고 넘어가도 괜찮을 거같습니다. 이는 나중에 또 사용하게 됩니다.

6. 로그인/로그아웃

1. Template

아래와 같이 login.html을 작성한 후 이를 templates > registration에 저장합니다.

<html><body>

<!-- Login Form --> <form id="login" method="post" action="{% url 'login_url' %}"> {% csrf_token %} {{ form.as_table }} </form>

</body></html>

Page 38: QnA blog using Django - ORM, 회원가입, 로그인/로그아웃

위에서 회원가입할 때와 비슷하게 생겼죠!?

우리는 로그인/로그아웃을 Django에서 만들어준 것을 이용할 것입니다. Django에서 폼 양식을 템플릿파일에 보낼 때 form 이라는 이름으로 렌더링해서 보내줍니다. 이는 AuthenticationForm 이라는폼 클래스를 통해서 만든 객체 이름이 form 이고 login 함수에서 이를 이용해 템플릿에 보내 준 것입니다.

2. View

저희는 함수를 직접 만들지 않고 Django에서 기본적으로 만들어 놓은 함수를 사용하겠습니다. 경로는 아래와 같습니다. 이 함수를 아래에서 URL에 적용할 것입니다.

django.contrib.auth.views.login

django.contrib.auth.views.logout

3. URL

시작 패키지 디렉토리에 있는 urls.py에 아래의 내용을 입력합니다.

url(r'̂ login/$', 'django.contrib.auth.views.login', name='login_url'),url(r'̂ logout/$', 'django.contrib.auth.views.logout', { 'next_page': '/login/', }, name='logout_url'),

각각 hostname/login과 hostname/logout으로 접속했을 때 Django에서 미리 만들어 놓은 함수로 이동하게 해주었습니다.

logout 에서는 next_page라는 인자값을 넣어주었습니다. 로그아웃하고 나서 이동할 페이지를 설정해주는 것입니다.

자, 이제 완료했습니다. 적당한 이름으로 회원 가입을 하고 로그인/로그아웃을 해봅시다. 아직은 UI를 만들지 않았기 때문에 버튼을 클릭할 게 없지요, 그래서 우선 URL을 직접 입력해서 들어가보겠습니다.

Appendix. Social Login

Page 39: QnA blog using Django - ORM, 회원가입, 로그인/로그아웃

[bitbucket.org 로그인 화면]

이제는 시대가 달라져서 다른 사이트에 가입했던 정보로 회원 가입과 로그인을 할 수 있게 되었습니다. 참재미난 세상입니다.

1. OAuth(Open standard for Authorization)

이렇게 다른 앱을 통해 회원가입이 가능해진 이유가 OAuth라는 것 때문입니다. 2006년 11월, Ma.gnolia에서 Twitter에게 OpenID에 대한 권한을 위임하면서 생겨났습니다. 본격적으로 2007년 4월 OAuthdiscussion group에서 open protocol에 대한 제안서를 쓰기 시작하여 현재 OAuth2.0까지 발전해온 것입니다.

자세한 내용은 Wikipedia를 확인해 보시기 바랍니다.

2. How to add to a Django app

1) Installing python-social-auth

먼저 해야할 것은 python-social-auth 패키지를 설치하는 것입니다. 쉽게 Third party authentication을얻게 해주는 패키지입니다.

sudo pip install python-social-auth

위와 같이 pip으로 설치해주면 끝납니다

Page 40: QnA blog using Django - ORM, 회원가입, 로그인/로그아웃

2) Setting settings.py

settings.py에서 설정해줘야하는 것은 아래에 있습니다.

1. INSTALLED_APPS에 항목 추가 새롭게 설치한 python-social-auth app을 추가합니다.이제 새롭게 User social auths 테이블에 생성되어 Thrid party로 가입한 사용자를 관리할수 있습니다.

2. TEMPLATE_CONTEXT_PROCESSORS에 항목 추가 social.apps.django_app.context_processors.backendssocial.apps.django_app.context_processors.login_redirect

3. AUTHENTICATION_BACKENDS 새롭게 추가 인증 체계에 사용될 backend를 등록하는 항목기본으로 django.contrib.auth.backends.ModelBackendpython-social-auth의 f acebook을 추가

4 . OAuth 관련 변수 설정 1. SOCIAL_AUTH_LOGIN_REDIRECT_URL

로그인 후 되돌아올 URL

2. SOCIAL_AUTH_URL_NAMESPACE 인증 URL의 Namespace

3. SOCIAL_AUTH_FACEBOOK_KEY/Secret Facebook 인증 Key/Secret

4 . SESSION_SERIALIZER 세션 객체를 직렬화하는 처리기참고자료

위에 것을 다 완성시키면 아래 소스가 됩니다.

INSTALLED_APPS = ( ... 'social.apps.django_app.default', ...)

TEMPLATE_CONTEXT_PROCESSORS = ( 'django.contrib.auth.context_processors.auth', 'django.core.context_processors.debug', 'django.core.context_processors.i18n', 'django.core.context_processors.media', 'django.core.context_processors.static', 'django.core.context_processors.tz', 'django.contrib.messages.context_processors.messages',

Page 41: QnA blog using Django - ORM, 회원가입, 로그인/로그아웃

'social.apps.django_app.context_processors.backends', 'social.apps.django_app.context_processors.login_redirect',)

AUTHENTICATION_BACKENDS = ( 'social.backends.facebook.FacebookOAuth2', # 'social.backends.google.GoogleOAuth2', # 'social.backends.twitter.TwitterOAuth', 'django.contrib.auth.backends.ModelBackend',)

SOCIAL_AUTH_LOGIN_REDIRECT_URL = '/' SOCIAL_AUTH_URL_NAMESPACE = 'social'

# FacebookSOCIAL_AUTH_FACEBOOK_KEY = 'Facebook App ID' SOCIAL_AUTH_FACEBOOK_SECRET = 'Facebook App Secret Key'

# Google# SOCIAL_AUTH_GOOGLE_OAUTH2_KEY = ''# SOCIAL_AUTH_GOOGLE_OAUTH2_SECRET = ''

# Twitter# SOCIAL_AUTH_TWITTER_KEY = ''# SOCIAL_AUTH_TWITTER_SECRET = ''

SESSION_SERIALIZER = 'django.contrib.sessions.serializers.PickleSerializer'

3) URL 설정하기

시작 패키지의 urls.py를 아래와 같이 입력합니다.

url(r'', include('social.apps.django_app.urls', namespace='social')),

위에서 지정한 social의 경우 템플릿에서 아래처럼 사용할 수 있습니다.

<a href="{% url 'social:begin' 'facebook' %}?next={{ request.path }}">Login with Facebook</a>

1. in case of google url ‘social:begin’ ‘f acebook’ 대신에 ‘google-oauth2’를 입력

2. in case of twitter url ‘social:begin’ ‘f acebook’ 대신에 ‘twitter’를 입력

Page 42: QnA blog using Django - ORM, 회원가입, 로그인/로그아웃

필요에 따라 아래처럼 Django에서 기본으로 제공하는 login/logout을 가져올 수 있습니다.

url(r'', include('django.contrib.auth.urls', namespace='auth')),

위에서 지정한 auth라는 이름은 후에 템플릿에서 아래처럼 사용할 수 있습니다.

<a href="{% url 'auth:logout' %}?next={{ request.path }}">Logout</a>

4) Get Client IDs for the social sites

Facebook에서 Application ID, 즉 OAuth2 client ID를 획득하는 과정을 아래에서 살펴보겠습니다.

1. f acebook 개발자 사이트에 접속합니다.2. 상단 메뉴의 My Apps의 Add a New App 클릭합니다.3. 앱 종류는 웹 사이트를 선택합니다.4 . 앱 이름을 입력하고 Create New Facebook ID를 클릭합니다.5. 다른 앱의 테스트 앱인지 물어보는 팝업창이 나올 것입니다. No를 선택하고, 카테고리를 선택하고, Create App ID를 클릭합니다.

6. Site URL, Mobile Site URL 실제 도메인을 입력합니다. 아직 준비되어 있지 않으면 아무것나 입력해도 상관없습니다. 나중에 수정할 수 있습니다.

7. 6번까지 하면 정상적으로 새로운 앱을 다 만든 것입니다. 화면을 다시 Ref resh 하면 상단의 MyApps에 새롭게 생성된 앱이 보일 것입니다.

8. My Apps에서 새로 추가한 앱을 선택합니다.9. 이는 실제 운영할 서비스용 앱에 대한 설정 화면입니다. 따라서 테스트를 해보기 위해 좌측 메뉴 중

Test Apps를 클릭합니다.10. 우측 상단의 Create a Test App을 클릭하여 새롭게 추가합니다.11. 새롭게 생성한 Test App의 좌측 메뉴 중 Settings를 클릭하면 Basic, Advanced, Migrations가 나옵니다.

12. 그 중 Basic 탭에 있는 App Domains, Site URL, Mobile Site URL 모두 http://localhost/를 입력하고Save Changes 버튼을 클릭합니다. 우리가 테스트할 곳이기 때문에 localhost로 설정하는 것입니다.

13. 앱 등록을 모두 완료하였습니다. 축하합니다!

5) settings.py에 Key 입력

등록한 앱에서 App ID와 Secret Key를 settings.py에 미리 설정한 변수에 입력합니다.

SOCIAL_AUTH_FACEBOOK_KEY = 'Facebook App ID' SOCIAL_AUTH_FACEBOOK_SECRET = 'Facebook App Secret Key'

3. 정리

Page 43: QnA blog using Django - ORM, 회원가입, 로그인/로그아웃

이렇게 Facebook에 앱을 등록하여 받은 key값으로 본인의 Django 사이트에 로그인을 할 수 있습니다.위에 주석을 처리한 Google, Twitter 뿐만 아니라 Github, Google Plus 모두 가능합니다.

위 내용은 이 문서를 참고해서 작성했습니다.

Written by initialkommit@Study-Bee.