SlideShare uma empresa Scribd logo
1 de 43
Baixar para ler offline
4주차: 회원가입과 로그인/로그아웃
1. 학습목표
1. ORM 다루기
Django를 이용해 데이터베이스에 있는 데이터를 가져오고 저장하는 등 다뤄보도록 하겠습니다. 특히 이
번에는 회원가입 기능이므로 사용자로부터 회원 양식을 입력받아 저장하는 것을 다뤄볼 것입니다.
Django에서 기본적으로 제공하는 User 모델을 이용하겠습니다.
2. Form 다루기
데이터베이스에 저장하기 전에 먼저 데이터가 필요하겠지요? 그렇기 대문에 저번 시간에 배웠던 HTML의
폼 태그를 이용해 사용자로부터 값을 입력받는 것을 Django에서 처리해보도록 하겠습니다.
3. 로그인/로그아웃 이용하기
User Authentication의 기본 기능인 로그인과 로그아웃을 만들어보겠습니다. 이는 Django에서 기본적
으로 제공하는 기능을 사용하겠습니다.
2. Preview
[회원가입 화면]
[로그인 화면]
[로그아웃 화면]
3. ORM(Object Relational Mapping)
1. Database
[DBMS-Database-Table-Column&Row]
DBMS
RelationalDatabase, 즉 관계형 데이터베이스라고 합니다. 이런 데이터베이스는 위 그림에서와 같이
DBMS라고 부르는 시스템에 의해 관리됩니다. 우리가 흔히(?) 보던 오라클, MSSQL, MySQL 등이 이에 속
합니다. 단순히 데이터베이스만을 관리하는 것이 아니라 데이터베이스를 관리하는데 필요한 유저, 스키
마 정보 등을 함께 관리해주는 종합 관리 툴입니다. 기업이 사용하는 DBMS도 있지만 개인이 사용하는
DBMS도 있습니다. 대표적인 게 바로 Microsoft Access입니다.
우리가 개발할 때 사용하는 것은 SQLite3입니다. 이는 DBMS가 아니라 파일시스템입니다. 파일 하나로
만 존재하거든요. Django로 프로젝트를 생성하면 프로젝트 루트 디렉토리(프로젝트 최상위 디렉토리)에
db.sqlite3 라는 파일이 보일겁니다. 이것이 SQLite3가 사용하는 파일입니다. 굉장히 단순한 데이터
베이스이지만 개발할 떄는 매우 유용하게 사용합니다.
개발할 때는 이렇게 SQLite3로 사용하지만 나중에 서버에 업로드할 때는 Oracle 사의 MySQL이나
Stanford 대학교에서 만든 PostgreSQL같은 DBMS를 사용할 것입니다.
그 외에도 많습니다. MySQL이 Oracle 사로 넘어간 이후 오픈소스에 제약이 생겨 그에 반하는 DBMS가 만
들어졌는데 그것이 바로 MariaDB입니다. MySQL이나 MariaDB나 만든 개발자는 똑같아서 거의 같다고
합니다. 참고로 Maria는 개발자 딸 이름이라고 하네요.
또한, 관계형이 아닌 데이터베이스도 있습니다. 이를 NoSQL(Not Only SQL)이라고 부릅니다. 대표적으
로 MongoDB가 있습니다.
Table
데이터베이스 안에 Table(or Relation)이 있습니다. 이는 데이터를 담는 그릇입니다. 이 테이블은 열
(Column or Field or Attribute)과 행(Row or Record or Tuple)로 구성되어있습니다. 수많은 행 중에
단 하나의 행을 만들어주는 열이 있습니다. 이를 Primary Key라고 부릅니다.
Database
위에서 언급한 테이블을 모아놓은 것을 바로 데이터베이스라고 합니다.
Relational
그런데 데이터베이스이긴한데 관계형입니다. 데이터 간 특정 관계를 맺을 수 있다는 뜻입니다. 관계라는
특성을 통해 데이터베이스의 테이블을 설계하는 작업을 모델링이라고 부릅니다. 즉, 현실에 있는 것을 추
상화시키는 것을 말합니다.
간단한 예로써, 대한민국 국민인 정광윤 은 주민등록번호 라는 유일한 값으로 본인임을 증명할 수 있습니
다. 이 번호를 가지고 보험을 가입할 수 있구요. 이럴 때 정부 데이터베이스 의 국민 테이블 의 ‘나’라는 레
코드 에 나를 유일하게 해주는 값 즉, Primary Key 인 주민등록번호를 통해 보험회사에 가입을 할 수 있
습니다. 그 보험회사의 데이터베이스 는 정부 데이터베이스 를 참조하는 관계가 형성되는 것입니다. 참 쉽
쥬!?ㅎㅎ
2. 데이터를 다루는 방법
[어플리케이션이 데이터를 다루는 방법]
일반적으로 어플리케이션이 데이터를 참조하는 방법을 간단하게 도식화하면 위와 같습니다. 그 안에 데
이터를 가리키는 Cursor라는 것도 필요하지만 그렇게 구체적으로 나가지는 않겠습니다.
우리가 데이터베이스의 데이터를 참조하기 위해선 다리(Connection) 를 놓고 그 위로
SQL(Structured Query Language)이라고 부르는 데이터베이스가 이해할 수 있는 언어로 Query(질
의) 를 해야합니다.
그런 질의문으로는 Select, Insert 같은 것이 있습니다.
이렇게 SQL 언어로 질의를 하면 데이터베이스는 그 질의를 이해하고 데이터를 어플리케이션에 반환해주
는 것입니다.
즉 우리는 데이터베이스에 필요한 데이터를 가져오기 위해선 질의문(SQL) 을 알아야 합니다.
3. SQL을 몰라도 데이터를 알고 싶다!
그런데 말입니다. SQL을 몰라도 데이터를 참조하는 방법이 있습니다. 바로 ORM이라는 방법입니다. ORM
이라는 것은 객체(Object or Instance)를 통해 데이터를 불러오거나 수정 또는 삽입하는 등 데이터를 처리
할 수 있는 방법입니다. Django가 이 ORM을 사용하고 있습니다. 즉, 우리가 개발할 블로그에서는 SQL을
몰라도 된다는 뜻입니다.
NOTE
물론 고도화된 서비스를 구축할 때 SQL을 사용할 떄도 있습니다. 따라서 더 전문적인 개발자가
되기 위해선 SQL을 알아야 합니다.
4. Django에서의 ORM
[ModelTemplate 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)
[Django에서의 ORM]
즉, Django에서는 모델( models.py )에 만든 클래스(Class)를 통해 객체(Object or Instance)를 만들
고, 이 객체를 통해 Database에 접근하게 됩니다. 이 것을 도식화한 것이 위의 그림입니다.
5. SQL VS. ORM
항목 방법
SQL Select username from USER where id=1;
ORM User.objects.get(id=1).username
위는 id 가 1 인 사용자의 사용자 이름(username) 을 가져오는 방법입니다. 그런데 이렇게면 보면
ORM의 장점이 별로 없어 보이네요^^;; 하지만 위 예제보다 복잡도가 높은 어플리케이션에서 ORM으로 개
발하면 코드를 좀 더 단순하고 깔끔하게 구현할 수 있습니다. 이에 생산성이 높아지며 테스트 또한 쉽게
할 수 있습니다.
6. 클래스와 객체의 관계
위에서 설명했듯이 ORM은 객체를 통해 Data를 Handling하는 방법입니다. 그렇기 때문에 클래스와 객체
의 관계를 좀 더 살펴볼 필요가 있습니다.
[클래스와 객체]
위의 그림처럼 Django에서 미리 만든 Model을 상속받아 사용자 정의 모델을 만들고 이 클래스의 객체를
통해 Database에 접근하게 됩니다. 이와 같이 객체는 클래스를 통해 만들어지게 됩니다.
이게 가능한 이유가 파이썬의 모든 것은 객체이기 때문입니다. 객체에는 속성(Properties)과 행동
(Action)이 있습니다. 위 그림에서는 get이라는 행동(함수)을 통해 데이터베이스에서 id 가 1 인 데이터
를 반환해 오는 것입니다.
여기서 객체는 클래스를 통해 만들어지는 구조를 보는 게 중요합니다. 그렇기 때문에 Django에서도
Class를 먼저 만드는 작업을 할 것입니다.
정말 중요합니다. 객체(인스턴스라고도 부릅니다. 똑같은 뜻입니다.)는 클래스라는 틀을 통해 만들어지
는 붕어빵과 같다고 보시면 됩니다.
7. Model: ORM에서 테이블 정의하기
데이터베이스에서 테이블은 데이터를 담는 그릇입니다. 이 그릇의 구조를 RDBMS에서 만들수도 있고,
SQL문을 통해 만들수도 있습니다. ORM에서는 데이터를 담는 그릇을 어떻게 정의할까요? 바로 위에서
계속해서 언급했던 Model(models.py)입니다. 먼저 ORM이 아닐 때를 보겠습니다.
1) 다른 툴로 만들 때
[Table의 구조 설계]
위 그림과 같이 테이블 구조를 설계한다고 가정했을 때 DBMS로 직접 데이블을 만들 수 있습니다. 또한
CREATE ... 로 시작하는 SQL로 테이블을 만들기도 합니다. 이렇게 테이블을 설계하고 만들 때 파이썬
과 같은 프로그래밍 언어로 처리하는 것이 아니라 데이터베이스를 직접 Handling 합니다.
그리고 데이터를 담으면 아래와 같은 모습이 됩니다.
[Table의 데이터를 GUI형태로 본 모습]
2) ORM으로 만들 때
[ORM방식으로 구조 설계]
하지만 ORM방식은 DBMS나 SQL과는 상관이 없습니다. 객체로 데이터베이스에 접근하는 방식이기 때문
이지요. 그렇기 때문에 파이썬과 같은 프로그래밍 언어로 클래스를 만들어주면 됩니다. 위 그림과 같이
클래스를 선언하고 아래에 속성으로 필드를 정의해주는 것입니다.
이렇게 Django는 데이터베이스의 테이블에 해당하는 클래스를 Model(models.py) 에서 정의합니
다. 이것이 바로 MTV Pattern의 Model부분인 것입니다.
8. Model Manager in Django
하나면 더 보고 가겠습니다. 이제 우리는 models.py 에서 만들어진 클래스를 통해 객체를 만들어 데이
터베이스에 접근한다는 것을 알았습니다. 이렇게 끝나는 줄 알았는데, Model Manager라는 것은 무엇일
까요?
특정 모델에 있는 모든 데이터를 가져올 때는 아래와 같이 작성합니다.
클래스.objects.all()
특정 모델에 id 가 1 인 값을 가져올 때는 아래와 같이 작성합니다.
클래스.objects.get(id=1)
위 예제를 보면 알겠지만 저는 만든 적도 없는데 클래스 뒤에 objects 가 붙는 걸 볼 수 있습니다. 이것
이 Django의 Modelmanager입니다.
Django의 공식 문서에는 아래와 같이 설명하고 있습니다.
A Manager is the interface through which database query operations are provided to
Django models. At least one Manager exists for every modelin a Django application. By
default, Django adds a Manager with the name objects to every Django modelclass.
위 설명처럼 objects라는 이름의 Modelmanager는 데이터베이스와 Django의 model 사이의 Query
operation(질의 연산)이 일어나는 인터페이스역할을 해줍니다.
이제 앞으로 클래스.objects 로 시작하는 것을 많이 보게 될 것입니다. 이것이 데이터베이스와의 인터
페이스 역할을 하기 때문에 Query operation 즉, 데이터를 찾고 입력하는 등의 핸들링을 할 수 있는 것입
니다. 특히 다수의 데이터를 가져오는 함수를 사용할 때 반환되는 객체를 QuerySet이라고 부릅니다. 이
것은 나중에 또 보도록 하겠습니다.
아래 공식 문서를 링크할테니 참고해서 보시면 더 좋을 것 같습니다.
1. Manager 클래스 동작 원리
2. QuerySet API
4. Django에서 데이터 다루기
위에서 우리는 Django를 이용해 데이터베이스의 데이터에 어떻게 접근하는지 열심히 배웠습니다. 이제
는 실제로 실습을 해보겠습니다. 기본적으로 데이터를 생성하고 읽고 갱신하고 삭제하는 것을 이르러
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
[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
[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라는 클래스를 이제부터 사용하겠다! 라는 뜻입니다.
NOTE
파이썬에서는 디렉토리가 패키지입니다.
파이썬에서는 파일이 모듈입니다.
파이썬에서는 관례상 대문자로 시작하는 객체는 클래스입니다.
주의사항
만약에 위와 같이 선언한 부분 위에서 User 클래스를 사용한다면?
파이썬은 순서대로 실행을 하기 때문에 위에서 사용한다면 에러가 납니다. 반드시 위와 같이 선
언한 아래부분부터 User 클래스를 사용해야 합니다.
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
first_name CharField varchar(30)
last_name CharField varchar(30)
email EmailField varchar(75)
is_staff 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
객체명 = 클래스명(인자=인자값)
위 방법대로 객체를 생성하면 클래스에 있던 속성과 메소드를 그대로 물려받은 붕어빵이 생기게 되는 것
입니다. 위 방법으로 사용자를 추가해보겠습니다.
user1 = User(username='test1', email='test1@test.com')
user1.set_password('test')
user1.save()
user2 = User(username='test2', email='test2@test.com')
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
1) 데이터 불러오기
all()
아래와 같이 입력하여 User 모델에 있는 모든 데이터를 불러와 보겠습니다.
User.objects.all()
first()
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()
위와 같이 실행했을 떄는 테이블의 Row에 해당하는 데이터가 나오는 것이 아니고, 하나의 객체가 나옵니
다. 각 객체의 데이터가 무엇인지 알아보기 위해서는 아래와 같이 values() 함수를 사용합니다. 이 때
반환값은 {key:value} 의 형태를 띄는 사전 객체라는 것을 유의하시기 바랍니다.
User.objects.values()
특정 컬럼의 값만 알고 싶다면 아래와 같이 인자값으로 필드명을 넘겨줍니다.
User.objects.values('username')
values_list()
values() 가 사전 객체로 보여줬다며, values_list() 함수는 key가 빠진 value값만 보여줍니다.
User.objects.values_list('username')
NOTE
values() 와 values_list() 함수는 QuerySet일 때만 가능합니다.
2) 조건 검색
아래와 같이 get과 filter를 통해 조건 검색을 할 수 있습니다.
User.objects.get(username='test')
User.objects.filter(email='test@test.com')
여러 조건 중에 아래와 같이 username 필드에서 ‘test’로 시작하는 데이터만 가져올 수 있도록 처리해줄
수 있습니다.
필드__옵션
User.objects.filter(username__startswith='test')
NOTE
get() 함수를 사용할 경우 반환값은 조건에 해당하는 객체가 됩니다. 그러나 filter() 함수
를 사용하여 나온 반환값은 QuerySet 객체가 됩니다. 질의(Query)를 해 여러 개의(Set) 데이터
가 나올 수 있기 때문입니다. 그래서 get() 함수의 반환값을 잘 보면 <...> 이렇게 생겼고
filter() 의 반환값은 [<...>,] 이렇게 생겼습니다. 즉, 리스트 안에 객체를 담은 것입니다.
3) Field Lookups
필드__옵션
위에서 실습해 보았던 filter(username__startswith) 의 Double underscore(__) 오른쪽을 Field
Lookups라고 부릅니다. 굉장히 다양한데 아래를 참고하시기 바랍니다. 이는 공식 문서에서 일부 가져온
내용입니다.
Name Desc. Example
exact Case-sensitive exact
match
Entry.objects.get(id__exact=14)
iexact Case-insensitive
exact match
Blog.objects.get(name__iexact=’beatles blog’)
contains Case-sensitive
containment test
Entry.objects.get(headline__contains=’Lennon’)
icontains Case-insensitive
containment test
Entry.objects.get(headline__icontains=’Lennon’)
in In a given list, or 조건 Entry.objects.filter(id__in=[1, 3, 4])
gt Greater than Entry.objects.filter(id__gt=4)
gte Greater than or equal
to
lt Less than
lte Less than or equalto
startswith Case-sensitive
starts-with
User.objects.filter(username__startswith=’test’)
istartswith Case-insensitive
starts-with
User.objects.filter(username__istartswith=’test’)
endswith Case-sensitive ends-
with
iendswith Case-insensitive
ends-with
range Between dates Entry.objects.filter(pub_date__range=
(datetime.date(2015,1,1), datetime.date(2015,1,31))
isnull Takes either T/F User.objects.filter(first_name__isnull=True)
Name Desc. Example
6. Update
값을 수정할 때 사용합니다. update() 함수는 QuerySet에 있는 함수이며 save() 가 함께 있습니다.
User.objects.filter(username='test').update(email='test@gmail.com')
User.objects.all().update(email='email@email.com')
User.objects.filter(username__startswith='test').update(email='email@em
ail.com')
그렇다면 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() 함수를 사용하면 되겠지요.
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':'legend@studybee.kr'})
get_or_create() 함수와 비슷합니다. 만약 first_name 이 John 이면서, last_name 이
Lennon 인 데이터가 있으면 defaults={ ... } 에 있는 내용으로 update 하고 없으면 생성해줍니
다.
3) count()
데이터의 갯수를 셀 수 있습니다.
User.objects.count()
4) exists()
모델에 데이터가 있는 지 유무를 판단할 수 있습니다. 반환값은 True or False 입니다.
User.objects.exists()
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) 환경 설정
우선 템플릿을 사용하기 위해선 환경 설정을 해줘야 합니다.
Template이 저장될 디렉토리 만들기
[프로젝트 전체 구조]
먼저 우리가 만들 signup.html 파일이 저장될 디렉토리를 만들겠습니다. 프로젝트 최상위 경로에서
아래오 같이 실행합니다.
$ mkdir templates
$ cd templates
$ mkdir registration
디렉토리 이름은 아무거나 입력해도 상관없지만 여기서는 templates 라고 하겠습니다. 그리고 그 하위
에 registration 이라는 디렉토리를 만들어서 회원가입과 로그인 관련 템플릿은 이 곳에 넣어두겠습
니다.
Template을 사용하겠다고 세팅하기
이제 template을 사용하겠다고 세팅을 해줘야 합니다. settings.py 에 아래와 같이 입력합니다.
# Build paths inside the project like this: os.path.join(BASE_DIR, ...)
import os
BASE_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 에 할당해준 것뿐입니다.
Template 파일에서 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라고 부릅니다.)을 보낼 때 일부 특수한 처리가 필요한 게 있습니다. 바로 그런 부분을
누가하는지 입력한 것입니다. 이는 외울 필요가 전~혀~ 없습니다. 그냥 복사 붙여넣기 하시면 됩니다. 심
지어 1.8 버전부터는 자동으로 세팅되어 나옵니다.
자세한 것은 공식 문서를 참고하시기 바랍니다.
2) Form태그
[회원가입 화면]
웹에서는 사용자에게 특정 값을 입력받아 오기 위해서는 HTML의 Form 태그를 반드시 사용해야 합니다.
우리말로 바꿔보면 ‘양식’이니, 맞는 말인 것 같습니다.
그리고 사용자에게 값을 입력받은 후 그 값이 요구한대로 적었는지 검사하는 검증 절차(Validation)를 거
쳐야 합니다. 예를 들어 email은 email형식대로 작성했는지를 검사하는 것을 말하는 것입니다.
Django에서는 이렇게 많이 쓰이는 Form 태그와 검증 절차를 이미 만들어 놓았습니다.
3) Django의 Form 이용해 만들기
fromdjango import forms
[ModelTemplate View 소프트웨어 아키텍쳐 패턴]
우리는 Django에 있는 Form 기능을 이제부터 사용할 것입니다. Django에서 제공하는 것은 크게 두 가지
가 있습니다.
1. django.forms.Form
2. django.forms.ModelForm
1번, 2번 모두 Form 태그를 만들어주고 Validation 기능도 있습니다. 하지만 2번의 경우는 조금 다른 게
있습니다.
사용자에게 입력한 값이 결국 데이터베이스에 저장되는 경우라면 2번을 사용하면 편리합니다. 해당
Form에 Model을 연결시켜놓은게 ModelForm이기 때문입니다. 우리는 사용자에게 사용자 정보를 입력
받아 User 모델에게 바로 저장하는 것이기 때문에 ModelForm을 사용하도록 하겠습니다.
UserCreationForm
그런데 Django는 회원가입 폼도 미리 만들어놨습니다!!! 감사한 일이지요? 위치는 아래와 같습니다.
from django.contrib.auth.forms import UserCreationForm
UserCreationForm 을 이용해서 만들면 아래와 같이 나옵니다.
[UserCreationForm]
미리 만들어놓은 폼에는 Username, Password, Password confirmation 이렇게 세 가지만 입력하게 되
어있습니다. 하지만 우리는 이메일을 하나 더 받을 생각입니다. 이번엔 UserCreationForm 으로만 작
성하고 다음 시간에 추가해보도록 하겠습니다.
4) html 만들기
signup.html
자, 지금까지 우리가 만들진 않았지만 Django에서 만들어놓은 것, 아래와 같은 두 가지를 이용할 준비(?)
가 다 되었습니다.
1. User 모델
2. UserCreationForm
이제는 템플릿 파일을 직접 만들어 보겠습니다. 아래와 같이 만들겠습니다.
<html>
<body>
<!-- Sign Up Form -->
<form id="signup" method="post" action="{% url 'signup' %}">
{% csrf_token %}
{{ userform.as_p }}
</form>
</body>
</html>
이렇게 만든 signup.html 을 프로젝트 최상위 디렉토리의 templates > registration 디렉토리
에 저장하겠습니다.
{% url ‘signup’ %}
urls.py에서 name이 signup으로 된 urlpattern으로 이동하라는 의미입니다. 이는 Django template
language이며 url은 함수입니다.
{% csrf_token %}
Cross-Site Request Forgery라는 공격 방법을 막을 수 있도록 Django에서 미리 기능을 제공합니다. 사용
자가 값을 입력해주는 Form 태그 시작부분에 무조건 써줘야 에러가 나지 않습니다.
{{ userform.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
이번엔 회원가입을 정상적으로 완료했을 때의 페이지를 만들겠습니다. 아래와 같습니다.
[회원 가입을 완료한 후의 페이지]
이 페이지는 로그인할 수 있도록 링크만 했을 뿐 사용자에게 어떤 값을 입력받는 등의 기능은 없습니다.
예쁘게 옷을 덧입는 것은 다음 시간에 차차 하도록 하고 오늘은 기능 구현에만 집중하겠습니다. 아래와 같
이 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>
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
from django.http import HttpResponseRedirect
from django.core.urlresolvers import reverse
from 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이라는 객체를 만들어라
userform = UserCreationForm()
return render(request, "registration/signup.html", {
"userform": userform,
})
그리고 render 라는 함수를 이용해서 두 번째 인가값인 템플릿 파일에 세 번째 인값과 함께 렌더링해서
보내주게 됩니다. 이 세 번째 인자값에 바로 우리가 위에서 만든 userform 객체를 사전 객체로 보내줍니
다.
POST 방식일 때
if request.method == "POST":
userform = UserCreationForm(request.POST)
if userform.is_valid():
userform.save()
return HttpResponseRedirect(
reverse("signup_ok")
)
UserCreationForm클래스로부터 userform이라는 객체를 만들자!
먼저 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주소를 입
력해줍니다. 이 함수는 우리가 urls.py 에서 name으로 지정했던 URL을 의미합니다.
return HttpResponseRedirect(
reverse("signup_ok")
)
우리가 사용할 객체를 잊지말고 선언하자!
우리는 위에서 UserCreationForm , HttpResponseRedirect , reverse 라는 것을 사용했습니다.
이미 만들어져 있는 어떤 객체를 사용하기 위해서 이렇게 먼저 선언을 해주는 작업이 필요합니다. 꼭 잊지
말고 해줘야합니다.
from django.http import HttpResponseRedirect
from django.core.urlresolvers import reverse
from django.contrib.auth.forms import UserCreationForm
4. URL
1) 회원가입 경로 설정
지금까지 우리는 아래의 것을 준비하였습니다.
1. User Model
2. UserCreationForm
3. 템플릿 파일
4. View
자, 이제는 마지막 하나가 남았습니다. 바로 사용자가 요청한 경로를 인식해 함수로 연결시켜주는
urls.py 입니다. 프로젝트와 이름이 같은 시작 패키지 디렉토리안에 urls.py 에 아래와 같이 작성하
도록 하겠습니다.
urlpatterns = patterns('',
# 중략,
url(r'^signup/$', 'qna.views.signup', name='signup'),
)
위와 같이 사용자가 http://hostname/signup 경로로 접속했을 때 바로 옆에 인자값인 qna 앱의
views 모듈의 방금 위에서 만든 signup 함수로 연결해주는 역할을 합니다.
2) 회원가입 완료 후 페이지 경로 설정
하나 더 추가하겠습니다. 회원가입을 정상적으로 완료했을 때의 페이지를 보여줄 수 있도록 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'),
)
TemplateView.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>
위에서 회원가입할 때와 비슷하게 생겼죠!?
우리는 로그인/로그아웃을 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
[bitbucket.org 로그인 화면]
이제는 시대가 달라져서 다른 사이트에 가입했던 정보로 회원 가입과 로그인을 할 수 있게 되었습니다. 참
재미난 세상입니다.
1. OAuth(Open standard for Authorization)
이렇게 다른 앱을 통해 회원가입이 가능해진 이유가 OAuth라는 것 때문입니다. 2006년 11월, Ma.gnolia
에서 Twitter에게 OpenID에 대한 권한을 위임하면서 생겨났습니다. 본격적으로 2007년 4월 OAuth
discussion 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으로 설치해주면 끝납니다
2) Setting settings.py
settings.py 에서 설정해줘야하는 것은 아래에 있습니다.
1. INSTALLED_APPS에 항목 추가
새롭게 설치한 python-social-auth app을 추가합니다.
이제 새롭게 User socialauths 테이블에 생성되어 Thrid party로 가입한 사용자를 관리할
수 있습니다.
2. TEMPLATE_CONTEXT_PROCESSORS에 항목 추가
social.apps.django_app.context_processors.backends
social.apps.django_app.context_processors.login_redirect
3. AUTHENTICATION_BACKENDS 새롭게 추가
인증 체계에 사용될 backend를 등록하는 항목
기본으로 django.contrib.auth.backends.ModelBackend
python-social-auth의 facebook을 추가
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',
'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'
# Facebook
SOCIAL_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’ ‘facebook’ 대신에 ‘google-oauth2’를 입력
2. in case of twitter
url‘social:begin’ ‘facebook’ 대신에 ‘twitter’를 입력
필요에 따라 아래처럼 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. facebook 개발자 사이트에 접속합니다.
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번까지 하면 정상적으로 새로운 앱을 다 만든 것입니다. 화면을 다시 Refresh 하면 상단의 My
Apps에 새롭게 생성된 앱이 보일 것입니다.
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. 정리
이렇게 Facebook에 앱을 등록하여 받은 key값으로 본인의 Django 사이트에 로그인을 할 수 있습니다.
위에 주석을 처리한 Google, Twitter 뿐만 아니라 Github, Google Plus 모두 가능합니다.
위 내용은 이 문서를 참고해서 작성했습니다.
Written by initialkommit@Study-Bee.

Mais conteúdo relacionado

Mais procurados

손쉬운 데이터 연결 방법(라이브바인딩 활용)
손쉬운 데이터 연결 방법(라이브바인딩 활용)손쉬운 데이터 연결 방법(라이브바인딩 활용)
손쉬운 데이터 연결 방법(라이브바인딩 활용)Devgear
 
Hibernate ppt
Hibernate pptHibernate ppt
Hibernate pptAneega
 
Django Rest Framework - Building a Web API
Django Rest Framework - Building a Web APIDjango Rest Framework - Building a Web API
Django Rest Framework - Building a Web APIMarcos Pereira
 
REST Easy with Django-Rest-Framework
REST Easy with Django-Rest-FrameworkREST Easy with Django-Rest-Framework
REST Easy with Django-Rest-FrameworkMarcel Chastain
 
Understanding REST
Understanding RESTUnderstanding REST
Understanding RESTNitin Pande
 
Módulo 7–Programación Web con Java.pdf
Módulo 7–Programación Web con Java.pdfMódulo 7–Programación Web con Java.pdf
Módulo 7–Programación Web con Java.pdftripfrap
 
Getting started with Next.js - IM Tech Meetup - Oct 2022.pptx
Getting started with Next.js - IM Tech Meetup - Oct 2022.pptxGetting started with Next.js - IM Tech Meetup - Oct 2022.pptx
Getting started with Next.js - IM Tech Meetup - Oct 2022.pptxIlesh Mistry
 
Node.js Tutorial for Beginners | Node.js Web Application Tutorial | Node.js T...
Node.js Tutorial for Beginners | Node.js Web Application Tutorial | Node.js T...Node.js Tutorial for Beginners | Node.js Web Application Tutorial | Node.js T...
Node.js Tutorial for Beginners | Node.js Web Application Tutorial | Node.js T...Edureka!
 
Advance Java Programming (CM5I) 6.Servlet
Advance Java Programming (CM5I) 6.ServletAdvance Java Programming (CM5I) 6.Servlet
Advance Java Programming (CM5I) 6.ServletPayal Dungarwal
 
React JS: A Secret Preview
React JS: A Secret PreviewReact JS: A Secret Preview
React JS: A Secret Previewvaluebound
 
React JS and why it's awesome
React JS and why it's awesomeReact JS and why it's awesome
React JS and why it's awesomeAndrew Hull
 
Python Django tutorial | Getting Started With Django | Web Development With D...
Python Django tutorial | Getting Started With Django | Web Development With D...Python Django tutorial | Getting Started With Django | Web Development With D...
Python Django tutorial | Getting Started With Django | Web Development With D...Edureka!
 

Mais procurados (20)

Spring data jpa
Spring data jpaSpring data jpa
Spring data jpa
 
손쉬운 데이터 연결 방법(라이브바인딩 활용)
손쉬운 데이터 연결 방법(라이브바인딩 활용)손쉬운 데이터 연결 방법(라이브바인딩 활용)
손쉬운 데이터 연결 방법(라이브바인딩 활용)
 
Introduction à JPA (Java Persistence API )
Introduction à JPA  (Java Persistence API )Introduction à JPA  (Java Persistence API )
Introduction à JPA (Java Persistence API )
 
Hibernate ppt
Hibernate pptHibernate ppt
Hibernate ppt
 
Django Rest Framework - Building a Web API
Django Rest Framework - Building a Web APIDjango Rest Framework - Building a Web API
Django Rest Framework - Building a Web API
 
Reactjs
ReactjsReactjs
Reactjs
 
REST Easy with Django-Rest-Framework
REST Easy with Django-Rest-FrameworkREST Easy with Django-Rest-Framework
REST Easy with Django-Rest-Framework
 
Spring Boot
Spring BootSpring Boot
Spring Boot
 
React JS
React JSReact JS
React JS
 
Spring Boot
Spring BootSpring Boot
Spring Boot
 
Spring MVC
Spring MVCSpring MVC
Spring MVC
 
Understanding REST
Understanding RESTUnderstanding REST
Understanding REST
 
Módulo 7–Programación Web con Java.pdf
Módulo 7–Programación Web con Java.pdfMódulo 7–Programación Web con Java.pdf
Módulo 7–Programación Web con Java.pdf
 
Getting started with Next.js - IM Tech Meetup - Oct 2022.pptx
Getting started with Next.js - IM Tech Meetup - Oct 2022.pptxGetting started with Next.js - IM Tech Meetup - Oct 2022.pptx
Getting started with Next.js - IM Tech Meetup - Oct 2022.pptx
 
Node.js Tutorial for Beginners | Node.js Web Application Tutorial | Node.js T...
Node.js Tutorial for Beginners | Node.js Web Application Tutorial | Node.js T...Node.js Tutorial for Beginners | Node.js Web Application Tutorial | Node.js T...
Node.js Tutorial for Beginners | Node.js Web Application Tutorial | Node.js T...
 
Advance Java Programming (CM5I) 6.Servlet
Advance Java Programming (CM5I) 6.ServletAdvance Java Programming (CM5I) 6.Servlet
Advance Java Programming (CM5I) 6.Servlet
 
React JS: A Secret Preview
React JS: A Secret PreviewReact JS: A Secret Preview
React JS: A Secret Preview
 
React JS and why it's awesome
React JS and why it's awesomeReact JS and why it's awesome
React JS and why it's awesome
 
React js
React jsReact js
React js
 
Python Django tutorial | Getting Started With Django | Web Development With D...
Python Django tutorial | Getting Started With Django | Web Development With D...Python Django tutorial | Getting Started With Django | Web Development With D...
Python Django tutorial | Getting Started With Django | Web Development With D...
 

Destaque

What's new, what's hot in PHP 5.3
What's new, what's hot in PHP 5.3What's new, what's hot in PHP 5.3
What's new, what's hot in PHP 5.3Jeremy Coates
 
Ling to SQL and Entity Framework performance analysis
Ling to SQL and Entity Framework performance analysisLing to SQL and Entity Framework performance analysis
Ling to SQL and Entity Framework performance analysisAlexander Konduforov
 
About Orm.fm
About Orm.fmAbout Orm.fm
About Orm.fmOrm Moon
 
좌충우돌 ORM 개발기 | Devon 2012
좌충우돌 ORM 개발기 | Devon 2012좌충우돌 ORM 개발기 | Devon 2012
좌충우돌 ORM 개발기 | Devon 2012Daum DNA
 
Object Relational Mapping in PHP
Object Relational Mapping in PHPObject Relational Mapping in PHP
Object Relational Mapping in PHPRob Knight
 
좌충우돌 ORM 개발기 2012 DAUM DEVON
좌충우돌 ORM 개발기 2012 DAUM DEVON좌충우돌 ORM 개발기 2012 DAUM DEVON
좌충우돌 ORM 개발기 2012 DAUM DEVONYounghan Kim
 
JDXA, The KISS ORM for Android
JDXA, The KISS ORM for AndroidJDXA, The KISS ORM for Android
JDXA, The KISS ORM for AndroidDamodar Periwal
 
ORM: Object-relational mapping
ORM: Object-relational mappingORM: Object-relational mapping
ORM: Object-relational mappingAbhilash M A
 
Object-Relational Mapping and Dependency Injection
Object-Relational Mapping and Dependency InjectionObject-Relational Mapping and Dependency Injection
Object-Relational Mapping and Dependency InjectionShane Church
 
03 Object Relational Mapping
03 Object Relational Mapping03 Object Relational Mapping
03 Object Relational MappingRanjan Kumar
 
Object Relational Mapping In Real World Applications
Object Relational Mapping In Real World ApplicationsObject Relational Mapping In Real World Applications
Object Relational Mapping In Real World ApplicationsPhilWinstanley
 
ORM을 활용할 경우의 설계, 개발 과정
ORM을 활용할 경우의 설계, 개발 과정ORM을 활용할 경우의 설계, 개발 과정
ORM을 활용할 경우의 설계, 개발 과정Javajigi Jaesung
 
Automated functional size measurement for three tier object relational mappin...
Automated functional size measurement for three tier object relational mappin...Automated functional size measurement for three tier object relational mappin...
Automated functional size measurement for three tier object relational mappin...IWSM Mensura
 
기술적 변화를 이끌어가기
기술적 변화를 이끌어가기기술적 변화를 이끌어가기
기술적 변화를 이끌어가기Jaewoo Ahn
 
SK플래닛_README_마이크로서비스 아키텍처로 개발하기
SK플래닛_README_마이크로서비스 아키텍처로 개발하기SK플래닛_README_마이크로서비스 아키텍처로 개발하기
SK플래닛_README_마이크로서비스 아키텍처로 개발하기Lee Ji Eun
 

Destaque (17)

What's new, what's hot in PHP 5.3
What's new, what's hot in PHP 5.3What's new, what's hot in PHP 5.3
What's new, what's hot in PHP 5.3
 
Ling to SQL and Entity Framework performance analysis
Ling to SQL and Entity Framework performance analysisLing to SQL and Entity Framework performance analysis
Ling to SQL and Entity Framework performance analysis
 
About Orm.fm
About Orm.fmAbout Orm.fm
About Orm.fm
 
좌충우돌 ORM 개발기 | Devon 2012
좌충우돌 ORM 개발기 | Devon 2012좌충우돌 ORM 개발기 | Devon 2012
좌충우돌 ORM 개발기 | Devon 2012
 
L16 Object Relational Mapping and NoSQL
L16 Object Relational Mapping and NoSQLL16 Object Relational Mapping and NoSQL
L16 Object Relational Mapping and NoSQL
 
Object Relational Mapping in PHP
Object Relational Mapping in PHPObject Relational Mapping in PHP
Object Relational Mapping in PHP
 
좌충우돌 ORM 개발기 2012 DAUM DEVON
좌충우돌 ORM 개발기 2012 DAUM DEVON좌충우돌 ORM 개발기 2012 DAUM DEVON
좌충우돌 ORM 개발기 2012 DAUM DEVON
 
JDXA, The KISS ORM for Android
JDXA, The KISS ORM for AndroidJDXA, The KISS ORM for Android
JDXA, The KISS ORM for Android
 
ORM: Object-relational mapping
ORM: Object-relational mappingORM: Object-relational mapping
ORM: Object-relational mapping
 
Object-Relational Mapping and Dependency Injection
Object-Relational Mapping and Dependency InjectionObject-Relational Mapping and Dependency Injection
Object-Relational Mapping and Dependency Injection
 
03 Object Relational Mapping
03 Object Relational Mapping03 Object Relational Mapping
03 Object Relational Mapping
 
L18 Object Relational Mapping
L18 Object Relational MappingL18 Object Relational Mapping
L18 Object Relational Mapping
 
Object Relational Mapping In Real World Applications
Object Relational Mapping In Real World ApplicationsObject Relational Mapping In Real World Applications
Object Relational Mapping In Real World Applications
 
ORM을 활용할 경우의 설계, 개발 과정
ORM을 활용할 경우의 설계, 개발 과정ORM을 활용할 경우의 설계, 개발 과정
ORM을 활용할 경우의 설계, 개발 과정
 
Automated functional size measurement for three tier object relational mappin...
Automated functional size measurement for three tier object relational mappin...Automated functional size measurement for three tier object relational mappin...
Automated functional size measurement for three tier object relational mappin...
 
기술적 변화를 이끌어가기
기술적 변화를 이끌어가기기술적 변화를 이끌어가기
기술적 변화를 이끌어가기
 
SK플래닛_README_마이크로서비스 아키텍처로 개발하기
SK플래닛_README_마이크로서비스 아키텍처로 개발하기SK플래닛_README_마이크로서비스 아키텍처로 개발하기
SK플래닛_README_마이크로서비스 아키텍처로 개발하기
 

Semelhante a QnA blog using Django - ORM, 회원가입, 로그인/로그아웃

[NEXT] Android 개발 경험 프로젝트 3일차 (Database)
 [NEXT] Android 개발 경험 프로젝트 3일차 (Database) [NEXT] Android 개발 경험 프로젝트 3일차 (Database)
[NEXT] Android 개발 경험 프로젝트 3일차 (Database)YoungSu Son
 
Django, 저는 이렇게 씁니다.
Django, 저는 이렇게 씁니다.Django, 저는 이렇게 씁니다.
Django, 저는 이렇게 씁니다.Kyoung Up Jung
 
QnA Blog Using Django - 회원가임/로그인폼, Post, 글보기
QnA Blog Using Django - 회원가임/로그인폼, Post, 글보기QnA Blog Using Django - 회원가임/로그인폼, Post, 글보기
QnA Blog Using Django - 회원가임/로그인폼, Post, 글보기Kwangyoun Jung
 
[HaU] 신입 기술 면접 준비 java
[HaU] 신입 기술 면접 준비 java[HaU] 신입 기술 면접 준비 java
[HaU] 신입 기술 면접 준비 java유리 하
 
[NEXT] Android 개발 경험 프로젝트 4일차 (Networking)
[NEXT] Android 개발 경험 프로젝트 4일차 (Networking)[NEXT] Android 개발 경험 프로젝트 4일차 (Networking)
[NEXT] Android 개발 경험 프로젝트 4일차 (Networking)YoungSu Son
 
[스프링 스터디 1일차] 템플릿
[스프링 스터디 1일차] 템플릿[스프링 스터디 1일차] 템플릿
[스프링 스터디 1일차] 템플릿AnselmKim
 
파이썬 플라스크 이해하기
파이썬 플라스크 이해하기 파이썬 플라스크 이해하기
파이썬 플라스크 이해하기 Yong Joon Moon
 
레거시 시스템에 Django 들이밀기
레거시 시스템에 Django 들이밀기레거시 시스템에 Django 들이밀기
레거시 시스템에 Django 들이밀기Jiyong Jung
 
XECon2015 :: [2-2] 박상현 - React로 개발하는 SPA 실무 이야기
XECon2015 :: [2-2] 박상현 - React로 개발하는 SPA 실무 이야기XECon2015 :: [2-2] 박상현 - React로 개발하는 SPA 실무 이야기
XECon2015 :: [2-2] 박상현 - React로 개발하는 SPA 실무 이야기XpressEngine
 
실전 DataSnap!
실전 DataSnap!실전 DataSnap!
실전 DataSnap!Devgear
 
LucideWorks Banana 소개
LucideWorks Banana 소개 LucideWorks Banana 소개
LucideWorks Banana 소개 SuHyun Jeon
 
ER/Studio 데이터 모델링 솔루션으로 마이그레이션(from ERwin)
ER/Studio 데이터 모델링 솔루션으로 마이그레이션(from ERwin)ER/Studio 데이터 모델링 솔루션으로 마이그레이션(from ERwin)
ER/Studio 데이터 모델링 솔루션으로 마이그레이션(from ERwin)Devgear
 
XE 오픈 세미나(2014-04-26) - 김동현 "XE 코어 구조론"
XE 오픈 세미나(2014-04-26) - 김동현 "XE 코어 구조론"XE 오픈 세미나(2014-04-26) - 김동현 "XE 코어 구조론"
XE 오픈 세미나(2014-04-26) - 김동현 "XE 코어 구조론"XpressEngine
 
Json view 예제 설명
Json view 예제 설명Json view 예제 설명
Json view 예제 설명Hyung Eun Jin
 
Java script 강의자료_ed13
Java script 강의자료_ed13Java script 강의자료_ed13
Java script 강의자료_ed13hungrok
 
Implementing_AOP_in_Spring_SYS4U
Implementing_AOP_in_Spring_SYS4UImplementing_AOP_in_Spring_SYS4U
Implementing_AOP_in_Spring_SYS4Usys4u
 
AWS DevDay 실습 가이드 - Rekognition 기반 Twitter봇
AWS DevDay 실습 가이드 - Rekognition 기반 Twitter봇AWS DevDay 실습 가이드 - Rekognition 기반 Twitter봇
AWS DevDay 실습 가이드 - Rekognition 기반 Twitter봇Amazon Web Services Korea
 
절차지향 vs 객체지향
절차지향 vs 객체지향절차지향 vs 객체지향
절차지향 vs 객체지향QooJuice
 

Semelhante a QnA blog using Django - ORM, 회원가입, 로그인/로그아웃 (20)

[NEXT] Android 개발 경험 프로젝트 3일차 (Database)
 [NEXT] Android 개발 경험 프로젝트 3일차 (Database) [NEXT] Android 개발 경험 프로젝트 3일차 (Database)
[NEXT] Android 개발 경험 프로젝트 3일차 (Database)
 
Django, 저는 이렇게 씁니다.
Django, 저는 이렇게 씁니다.Django, 저는 이렇게 씁니다.
Django, 저는 이렇게 씁니다.
 
QnA Blog Using Django - 회원가임/로그인폼, Post, 글보기
QnA Blog Using Django - 회원가임/로그인폼, Post, 글보기QnA Blog Using Django - 회원가임/로그인폼, Post, 글보기
QnA Blog Using Django - 회원가임/로그인폼, Post, 글보기
 
[HaU] 신입 기술 면접 준비 java
[HaU] 신입 기술 면접 준비 java[HaU] 신입 기술 면접 준비 java
[HaU] 신입 기술 면접 준비 java
 
[NEXT] Android 개발 경험 프로젝트 4일차 (Networking)
[NEXT] Android 개발 경험 프로젝트 4일차 (Networking)[NEXT] Android 개발 경험 프로젝트 4일차 (Networking)
[NEXT] Android 개발 경험 프로젝트 4일차 (Networking)
 
[스프링 스터디 1일차] 템플릿
[스프링 스터디 1일차] 템플릿[스프링 스터디 1일차] 템플릿
[스프링 스터디 1일차] 템플릿
 
EC 789
EC 789EC 789
EC 789
 
12books
12books12books
12books
 
파이썬 플라스크 이해하기
파이썬 플라스크 이해하기 파이썬 플라스크 이해하기
파이썬 플라스크 이해하기
 
레거시 시스템에 Django 들이밀기
레거시 시스템에 Django 들이밀기레거시 시스템에 Django 들이밀기
레거시 시스템에 Django 들이밀기
 
XECon2015 :: [2-2] 박상현 - React로 개발하는 SPA 실무 이야기
XECon2015 :: [2-2] 박상현 - React로 개발하는 SPA 실무 이야기XECon2015 :: [2-2] 박상현 - React로 개발하는 SPA 실무 이야기
XECon2015 :: [2-2] 박상현 - React로 개발하는 SPA 실무 이야기
 
실전 DataSnap!
실전 DataSnap!실전 DataSnap!
실전 DataSnap!
 
LucideWorks Banana 소개
LucideWorks Banana 소개 LucideWorks Banana 소개
LucideWorks Banana 소개
 
ER/Studio 데이터 모델링 솔루션으로 마이그레이션(from ERwin)
ER/Studio 데이터 모델링 솔루션으로 마이그레이션(from ERwin)ER/Studio 데이터 모델링 솔루션으로 마이그레이션(from ERwin)
ER/Studio 데이터 모델링 솔루션으로 마이그레이션(from ERwin)
 
XE 오픈 세미나(2014-04-26) - 김동현 "XE 코어 구조론"
XE 오픈 세미나(2014-04-26) - 김동현 "XE 코어 구조론"XE 오픈 세미나(2014-04-26) - 김동현 "XE 코어 구조론"
XE 오픈 세미나(2014-04-26) - 김동현 "XE 코어 구조론"
 
Json view 예제 설명
Json view 예제 설명Json view 예제 설명
Json view 예제 설명
 
Java script 강의자료_ed13
Java script 강의자료_ed13Java script 강의자료_ed13
Java script 강의자료_ed13
 
Implementing_AOP_in_Spring_SYS4U
Implementing_AOP_in_Spring_SYS4UImplementing_AOP_in_Spring_SYS4U
Implementing_AOP_in_Spring_SYS4U
 
AWS DevDay 실습 가이드 - Rekognition 기반 Twitter봇
AWS DevDay 실습 가이드 - Rekognition 기반 Twitter봇AWS DevDay 실습 가이드 - Rekognition 기반 Twitter봇
AWS DevDay 실습 가이드 - Rekognition 기반 Twitter봇
 
절차지향 vs 객체지향
절차지향 vs 객체지향절차지향 vs 객체지향
절차지향 vs 객체지향
 

Mais de Kwangyoun Jung

장고로 웹서비스 만들기 기초
장고로 웹서비스 만들기   기초장고로 웹서비스 만들기   기초
장고로 웹서비스 만들기 기초Kwangyoun Jung
 
Virtual Development Environment Setting
Virtual Development Environment SettingVirtual Development Environment Setting
Virtual Development Environment SettingKwangyoun Jung
 
문과생 대상 파이썬을 활용한 데이터 분석 강의
문과생 대상 파이썬을 활용한 데이터 분석 강의문과생 대상 파이썬을 활용한 데이터 분석 강의
문과생 대상 파이썬을 활용한 데이터 분석 강의Kwangyoun Jung
 
Python+anaconda Development Environment
Python+anaconda Development EnvironmentPython+anaconda Development Environment
Python+anaconda Development EnvironmentKwangyoun Jung
 
Python, Development Environment for Windows
Python, Development Environment for WindowsPython, Development Environment for Windows
Python, Development Environment for WindowsKwangyoun Jung
 

Mais de Kwangyoun Jung (7)

python and database
python and databasepython and database
python and database
 
장고로 웹서비스 만들기 기초
장고로 웹서비스 만들기   기초장고로 웹서비스 만들기   기초
장고로 웹서비스 만들기 기초
 
Light Tutorial Python
Light Tutorial PythonLight Tutorial Python
Light Tutorial Python
 
Virtual Development Environment Setting
Virtual Development Environment SettingVirtual Development Environment Setting
Virtual Development Environment Setting
 
문과생 대상 파이썬을 활용한 데이터 분석 강의
문과생 대상 파이썬을 활용한 데이터 분석 강의문과생 대상 파이썬을 활용한 데이터 분석 강의
문과생 대상 파이썬을 활용한 데이터 분석 강의
 
Python+anaconda Development Environment
Python+anaconda Development EnvironmentPython+anaconda Development Environment
Python+anaconda Development Environment
 
Python, Development Environment for Windows
Python, Development Environment for WindowsPython, Development Environment for Windows
Python, Development Environment for Windows
 

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

  • 1. 4주차: 회원가입과 로그인/로그아웃 1. 학습목표 1. ORM 다루기 Django를 이용해 데이터베이스에 있는 데이터를 가져오고 저장하는 등 다뤄보도록 하겠습니다. 특히 이 번에는 회원가입 기능이므로 사용자로부터 회원 양식을 입력받아 저장하는 것을 다뤄볼 것입니다. Django에서 기본적으로 제공하는 User 모델을 이용하겠습니다. 2. Form 다루기 데이터베이스에 저장하기 전에 먼저 데이터가 필요하겠지요? 그렇기 대문에 저번 시간에 배웠던 HTML의 폼 태그를 이용해 사용자로부터 값을 입력받는 것을 Django에서 처리해보도록 하겠습니다. 3. 로그인/로그아웃 이용하기 User Authentication의 기본 기능인 로그인과 로그아웃을 만들어보겠습니다. 이는 Django에서 기본적 으로 제공하는 기능을 사용하겠습니다. 2. Preview
  • 4. [로그아웃 화면] 3. ORM(Object Relational Mapping) 1. Database
  • 5. [DBMS-Database-Table-Column&Row] DBMS RelationalDatabase, 즉 관계형 데이터베이스라고 합니다. 이런 데이터베이스는 위 그림에서와 같이 DBMS라고 부르는 시스템에 의해 관리됩니다. 우리가 흔히(?) 보던 오라클, MSSQL, MySQL 등이 이에 속 합니다. 단순히 데이터베이스만을 관리하는 것이 아니라 데이터베이스를 관리하는데 필요한 유저, 스키 마 정보 등을 함께 관리해주는 종합 관리 툴입니다. 기업이 사용하는 DBMS도 있지만 개인이 사용하는 DBMS도 있습니다. 대표적인 게 바로 Microsoft Access입니다. 우리가 개발할 때 사용하는 것은 SQLite3입니다. 이는 DBMS가 아니라 파일시스템입니다. 파일 하나로 만 존재하거든요. Django로 프로젝트를 생성하면 프로젝트 루트 디렉토리(프로젝트 최상위 디렉토리)에 db.sqlite3 라는 파일이 보일겁니다. 이것이 SQLite3가 사용하는 파일입니다. 굉장히 단순한 데이터 베이스이지만 개발할 떄는 매우 유용하게 사용합니다. 개발할 때는 이렇게 SQLite3로 사용하지만 나중에 서버에 업로드할 때는 Oracle 사의 MySQL이나 Stanford 대학교에서 만든 PostgreSQL같은 DBMS를 사용할 것입니다. 그 외에도 많습니다. MySQL이 Oracle 사로 넘어간 이후 오픈소스에 제약이 생겨 그에 반하는 DBMS가 만 들어졌는데 그것이 바로 MariaDB입니다. MySQL이나 MariaDB나 만든 개발자는 똑같아서 거의 같다고 합니다. 참고로 Maria는 개발자 딸 이름이라고 하네요.
  • 6. 또한, 관계형이 아닌 데이터베이스도 있습니다. 이를 NoSQL(Not Only SQL)이라고 부릅니다. 대표적으 로 MongoDB가 있습니다. Table 데이터베이스 안에 Table(or Relation)이 있습니다. 이는 데이터를 담는 그릇입니다. 이 테이블은 열 (Column or Field or Attribute)과 행(Row or Record or Tuple)로 구성되어있습니다. 수많은 행 중에 단 하나의 행을 만들어주는 열이 있습니다. 이를 Primary Key라고 부릅니다. Database 위에서 언급한 테이블을 모아놓은 것을 바로 데이터베이스라고 합니다. Relational 그런데 데이터베이스이긴한데 관계형입니다. 데이터 간 특정 관계를 맺을 수 있다는 뜻입니다. 관계라는 특성을 통해 데이터베이스의 테이블을 설계하는 작업을 모델링이라고 부릅니다. 즉, 현실에 있는 것을 추 상화시키는 것을 말합니다. 간단한 예로써, 대한민국 국민인 정광윤 은 주민등록번호 라는 유일한 값으로 본인임을 증명할 수 있습니 다. 이 번호를 가지고 보험을 가입할 수 있구요. 이럴 때 정부 데이터베이스 의 국민 테이블 의 ‘나’라는 레 코드 에 나를 유일하게 해주는 값 즉, Primary Key 인 주민등록번호를 통해 보험회사에 가입을 할 수 있 습니다. 그 보험회사의 데이터베이스 는 정부 데이터베이스 를 참조하는 관계가 형성되는 것입니다. 참 쉽 쥬!?ㅎㅎ 2. 데이터를 다루는 방법
  • 7. [어플리케이션이 데이터를 다루는 방법] 일반적으로 어플리케이션이 데이터를 참조하는 방법을 간단하게 도식화하면 위와 같습니다. 그 안에 데 이터를 가리키는 Cursor라는 것도 필요하지만 그렇게 구체적으로 나가지는 않겠습니다. 우리가 데이터베이스의 데이터를 참조하기 위해선 다리(Connection) 를 놓고 그 위로 SQL(Structured Query Language)이라고 부르는 데이터베이스가 이해할 수 있는 언어로 Query(질 의) 를 해야합니다. 그런 질의문으로는 Select, Insert 같은 것이 있습니다. 이렇게 SQL 언어로 질의를 하면 데이터베이스는 그 질의를 이해하고 데이터를 어플리케이션에 반환해주 는 것입니다. 즉 우리는 데이터베이스에 필요한 데이터를 가져오기 위해선 질의문(SQL) 을 알아야 합니다. 3. SQL을 몰라도 데이터를 알고 싶다! 그런데 말입니다. SQL을 몰라도 데이터를 참조하는 방법이 있습니다. 바로 ORM이라는 방법입니다. ORM 이라는 것은 객체(Object or Instance)를 통해 데이터를 불러오거나 수정 또는 삽입하는 등 데이터를 처리 할 수 있는 방법입니다. Django가 이 ORM을 사용하고 있습니다. 즉, 우리가 개발할 블로그에서는 SQL을 몰라도 된다는 뜻입니다. NOTE 물론 고도화된 서비스를 구축할 때 SQL을 사용할 떄도 있습니다. 따라서 더 전문적인 개발자가 되기 위해선 SQL을 알아야 합니다.
  • 8. 4. Django에서의 ORM [ModelTemplate 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)
  • 9. [Django에서의 ORM] 즉, Django에서는 모델( models.py )에 만든 클래스(Class)를 통해 객체(Object or Instance)를 만들 고, 이 객체를 통해 Database에 접근하게 됩니다. 이 것을 도식화한 것이 위의 그림입니다. 5. SQL VS. ORM 항목 방법 SQL Select username from USER where id=1; ORM User.objects.get(id=1).username 위는 id 가 1 인 사용자의 사용자 이름(username) 을 가져오는 방법입니다. 그런데 이렇게면 보면 ORM의 장점이 별로 없어 보이네요^^;; 하지만 위 예제보다 복잡도가 높은 어플리케이션에서 ORM으로 개 발하면 코드를 좀 더 단순하고 깔끔하게 구현할 수 있습니다. 이에 생산성이 높아지며 테스트 또한 쉽게 할 수 있습니다. 6. 클래스와 객체의 관계 위에서 설명했듯이 ORM은 객체를 통해 Data를 Handling하는 방법입니다. 그렇기 때문에 클래스와 객체 의 관계를 좀 더 살펴볼 필요가 있습니다.
  • 10. [클래스와 객체] 위의 그림처럼 Django에서 미리 만든 Model을 상속받아 사용자 정의 모델을 만들고 이 클래스의 객체를 통해 Database에 접근하게 됩니다. 이와 같이 객체는 클래스를 통해 만들어지게 됩니다. 이게 가능한 이유가 파이썬의 모든 것은 객체이기 때문입니다. 객체에는 속성(Properties)과 행동 (Action)이 있습니다. 위 그림에서는 get이라는 행동(함수)을 통해 데이터베이스에서 id 가 1 인 데이터 를 반환해 오는 것입니다. 여기서 객체는 클래스를 통해 만들어지는 구조를 보는 게 중요합니다. 그렇기 때문에 Django에서도 Class를 먼저 만드는 작업을 할 것입니다. 정말 중요합니다. 객체(인스턴스라고도 부릅니다. 똑같은 뜻입니다.)는 클래스라는 틀을 통해 만들어지 는 붕어빵과 같다고 보시면 됩니다.
  • 11. 7. Model: ORM에서 테이블 정의하기 데이터베이스에서 테이블은 데이터를 담는 그릇입니다. 이 그릇의 구조를 RDBMS에서 만들수도 있고, SQL문을 통해 만들수도 있습니다. ORM에서는 데이터를 담는 그릇을 어떻게 정의할까요? 바로 위에서 계속해서 언급했던 Model(models.py)입니다. 먼저 ORM이 아닐 때를 보겠습니다. 1) 다른 툴로 만들 때 [Table의 구조 설계] 위 그림과 같이 테이블 구조를 설계한다고 가정했을 때 DBMS로 직접 데이블을 만들 수 있습니다. 또한 CREATE ... 로 시작하는 SQL로 테이블을 만들기도 합니다. 이렇게 테이블을 설계하고 만들 때 파이썬 과 같은 프로그래밍 언어로 처리하는 것이 아니라 데이터베이스를 직접 Handling 합니다. 그리고 데이터를 담으면 아래와 같은 모습이 됩니다.
  • 12. [Table의 데이터를 GUI형태로 본 모습] 2) ORM으로 만들 때 [ORM방식으로 구조 설계] 하지만 ORM방식은 DBMS나 SQL과는 상관이 없습니다. 객체로 데이터베이스에 접근하는 방식이기 때문 이지요. 그렇기 때문에 파이썬과 같은 프로그래밍 언어로 클래스를 만들어주면 됩니다. 위 그림과 같이 클래스를 선언하고 아래에 속성으로 필드를 정의해주는 것입니다. 이렇게 Django는 데이터베이스의 테이블에 해당하는 클래스를 Model(models.py) 에서 정의합니
  • 13. 다. 이것이 바로 MTV Pattern의 Model부분인 것입니다. 8. Model Manager in Django 하나면 더 보고 가겠습니다. 이제 우리는 models.py 에서 만들어진 클래스를 통해 객체를 만들어 데이 터베이스에 접근한다는 것을 알았습니다. 이렇게 끝나는 줄 알았는데, Model Manager라는 것은 무엇일 까요? 특정 모델에 있는 모든 데이터를 가져올 때는 아래와 같이 작성합니다. 클래스.objects.all() 특정 모델에 id 가 1 인 값을 가져올 때는 아래와 같이 작성합니다. 클래스.objects.get(id=1) 위 예제를 보면 알겠지만 저는 만든 적도 없는데 클래스 뒤에 objects 가 붙는 걸 볼 수 있습니다. 이것 이 Django의 Modelmanager입니다. Django의 공식 문서에는 아래와 같이 설명하고 있습니다. A Manager is the interface through which database query operations are provided to Django models. At least one Manager exists for every modelin a Django application. By default, Django adds a Manager with the name objects to every Django modelclass. 위 설명처럼 objects라는 이름의 Modelmanager는 데이터베이스와 Django의 model 사이의 Query operation(질의 연산)이 일어나는 인터페이스역할을 해줍니다. 이제 앞으로 클래스.objects 로 시작하는 것을 많이 보게 될 것입니다. 이것이 데이터베이스와의 인터 페이스 역할을 하기 때문에 Query operation 즉, 데이터를 찾고 입력하는 등의 핸들링을 할 수 있는 것입 니다. 특히 다수의 데이터를 가져오는 함수를 사용할 때 반환되는 객체를 QuerySet이라고 부릅니다. 이 것은 나중에 또 보도록 하겠습니다. 아래 공식 문서를 링크할테니 참고해서 보시면 더 좋을 것 같습니다. 1. Manager 클래스 동작 원리 2. QuerySet API 4. Django에서 데이터 다루기 위에서 우리는 Django를 이용해 데이터베이스의 데이터에 어떻게 접근하는지 열심히 배웠습니다. 이제
  • 14. 는 실제로 실습을 해보겠습니다. 기본적으로 데이터를 생성하고 읽고 갱신하고 삭제하는 것을 이르러 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
  • 15. [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
  • 16. [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라는 클래스를 이제부터 사용하겠다! 라는 뜻입니다. NOTE 파이썬에서는 디렉토리가 패키지입니다. 파이썬에서는 파일이 모듈입니다. 파이썬에서는 관례상 대문자로 시작하는 객체는 클래스입니다. 주의사항 만약에 위와 같이 선언한 부분 위에서 User 클래스를 사용한다면? 파이썬은 순서대로 실행을 하기 때문에 위에서 사용한다면 에러가 납니다. 반드시 위와 같이 선 언한 아래부분부터 User 클래스를 사용해야 합니다.
  • 17. 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 first_name CharField varchar(30) last_name CharField varchar(30)
  • 18. email EmailField varchar(75) is_staff 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
  • 19. 객체명 = 클래스명(인자=인자값) 위 방법대로 객체를 생성하면 클래스에 있던 속성과 메소드를 그대로 물려받은 붕어빵이 생기게 되는 것 입니다. 위 방법으로 사용자를 추가해보겠습니다. user1 = User(username='test1', email='test1@test.com') user1.set_password('test') user1.save() user2 = User(username='test2', email='test2@test.com') 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
  • 20. 1) 데이터 불러오기 all() 아래와 같이 입력하여 User 모델에 있는 모든 데이터를 불러와 보겠습니다. User.objects.all() first() 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()
  • 21. 위와 같이 실행했을 떄는 테이블의 Row에 해당하는 데이터가 나오는 것이 아니고, 하나의 객체가 나옵니 다. 각 객체의 데이터가 무엇인지 알아보기 위해서는 아래와 같이 values() 함수를 사용합니다. 이 때 반환값은 {key:value} 의 형태를 띄는 사전 객체라는 것을 유의하시기 바랍니다. User.objects.values() 특정 컬럼의 값만 알고 싶다면 아래와 같이 인자값으로 필드명을 넘겨줍니다. User.objects.values('username') values_list() values() 가 사전 객체로 보여줬다며, values_list() 함수는 key가 빠진 value값만 보여줍니다. User.objects.values_list('username') NOTE values() 와 values_list() 함수는 QuerySet일 때만 가능합니다. 2) 조건 검색 아래와 같이 get과 filter를 통해 조건 검색을 할 수 있습니다. User.objects.get(username='test') User.objects.filter(email='test@test.com') 여러 조건 중에 아래와 같이 username 필드에서 ‘test’로 시작하는 데이터만 가져올 수 있도록 처리해줄 수 있습니다. 필드__옵션 User.objects.filter(username__startswith='test') NOTE get() 함수를 사용할 경우 반환값은 조건에 해당하는 객체가 됩니다. 그러나 filter() 함수 를 사용하여 나온 반환값은 QuerySet 객체가 됩니다. 질의(Query)를 해 여러 개의(Set) 데이터 가 나올 수 있기 때문입니다. 그래서 get() 함수의 반환값을 잘 보면 <...> 이렇게 생겼고
  • 22. filter() 의 반환값은 [<...>,] 이렇게 생겼습니다. 즉, 리스트 안에 객체를 담은 것입니다. 3) Field Lookups 필드__옵션 위에서 실습해 보았던 filter(username__startswith) 의 Double underscore(__) 오른쪽을 Field Lookups라고 부릅니다. 굉장히 다양한데 아래를 참고하시기 바랍니다. 이는 공식 문서에서 일부 가져온 내용입니다. Name Desc. Example exact Case-sensitive exact match Entry.objects.get(id__exact=14) iexact Case-insensitive exact match Blog.objects.get(name__iexact=’beatles blog’) contains Case-sensitive containment test Entry.objects.get(headline__contains=’Lennon’) icontains Case-insensitive containment test Entry.objects.get(headline__icontains=’Lennon’) in In a given list, or 조건 Entry.objects.filter(id__in=[1, 3, 4]) gt Greater than Entry.objects.filter(id__gt=4) gte Greater than or equal to lt Less than lte Less than or equalto startswith Case-sensitive starts-with User.objects.filter(username__startswith=’test’) istartswith Case-insensitive starts-with User.objects.filter(username__istartswith=’test’) endswith Case-sensitive ends- with iendswith Case-insensitive ends-with
  • 23. range Between dates Entry.objects.filter(pub_date__range= (datetime.date(2015,1,1), datetime.date(2015,1,31)) isnull Takes either T/F User.objects.filter(first_name__isnull=True) Name Desc. Example 6. Update 값을 수정할 때 사용합니다. update() 함수는 QuerySet에 있는 함수이며 save() 가 함께 있습니다. User.objects.filter(username='test').update(email='test@gmail.com') User.objects.all().update(email='email@email.com') User.objects.filter(username__startswith='test').update(email='email@em ail.com') 그렇다면 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() 함수를 사용하면 되겠지요.
  • 24. 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':'legend@studybee.kr'}) get_or_create() 함수와 비슷합니다. 만약 first_name 이 John 이면서, last_name 이 Lennon 인 데이터가 있으면 defaults={ ... } 에 있는 내용으로 update 하고 없으면 생성해줍니 다. 3) count() 데이터의 갯수를 셀 수 있습니다. User.objects.count() 4) exists() 모델에 데이터가 있는 지 유무를 판단할 수 있습니다. 반환값은 True or False 입니다. User.objects.exists()
  • 25. 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) 환경 설정 우선 템플릿을 사용하기 위해선 환경 설정을 해줘야 합니다. Template이 저장될 디렉토리 만들기
  • 26. [프로젝트 전체 구조] 먼저 우리가 만들 signup.html 파일이 저장될 디렉토리를 만들겠습니다. 프로젝트 최상위 경로에서
  • 27. 아래오 같이 실행합니다. $ mkdir templates $ cd templates $ mkdir registration 디렉토리 이름은 아무거나 입력해도 상관없지만 여기서는 templates 라고 하겠습니다. 그리고 그 하위 에 registration 이라는 디렉토리를 만들어서 회원가입과 로그인 관련 템플릿은 이 곳에 넣어두겠습 니다. Template을 사용하겠다고 세팅하기 이제 template을 사용하겠다고 세팅을 해줘야 합니다. settings.py 에 아래와 같이 입력합니다. # Build paths inside the project like this: os.path.join(BASE_DIR, ...) import os BASE_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 에 할당해준 것뿐입니다. Template 파일에서 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라고 부릅니다.)을 보낼 때 일부 특수한 처리가 필요한 게 있습니다. 바로 그런 부분을 누가하는지 입력한 것입니다. 이는 외울 필요가 전~혀~ 없습니다. 그냥 복사 붙여넣기 하시면 됩니다. 심
  • 28. 지어 1.8 버전부터는 자동으로 세팅되어 나옵니다. 자세한 것은 공식 문서를 참고하시기 바랍니다. 2) Form태그 [회원가입 화면] 웹에서는 사용자에게 특정 값을 입력받아 오기 위해서는 HTML의 Form 태그를 반드시 사용해야 합니다. 우리말로 바꿔보면 ‘양식’이니, 맞는 말인 것 같습니다. 그리고 사용자에게 값을 입력받은 후 그 값이 요구한대로 적었는지 검사하는 검증 절차(Validation)를 거
  • 29. 쳐야 합니다. 예를 들어 email은 email형식대로 작성했는지를 검사하는 것을 말하는 것입니다. Django에서는 이렇게 많이 쓰이는 Form 태그와 검증 절차를 이미 만들어 놓았습니다. 3) Django의 Form 이용해 만들기 fromdjango import forms [ModelTemplate View 소프트웨어 아키텍쳐 패턴] 우리는 Django에 있는 Form 기능을 이제부터 사용할 것입니다. Django에서 제공하는 것은 크게 두 가지 가 있습니다. 1. django.forms.Form 2. django.forms.ModelForm 1번, 2번 모두 Form 태그를 만들어주고 Validation 기능도 있습니다. 하지만 2번의 경우는 조금 다른 게 있습니다. 사용자에게 입력한 값이 결국 데이터베이스에 저장되는 경우라면 2번을 사용하면 편리합니다. 해당 Form에 Model을 연결시켜놓은게 ModelForm이기 때문입니다. 우리는 사용자에게 사용자 정보를 입력 받아 User 모델에게 바로 저장하는 것이기 때문에 ModelForm을 사용하도록 하겠습니다.
  • 30. UserCreationForm 그런데 Django는 회원가입 폼도 미리 만들어놨습니다!!! 감사한 일이지요? 위치는 아래와 같습니다. from django.contrib.auth.forms import UserCreationForm UserCreationForm 을 이용해서 만들면 아래와 같이 나옵니다. [UserCreationForm] 미리 만들어놓은 폼에는 Username, Password, Password confirmation 이렇게 세 가지만 입력하게 되 어있습니다. 하지만 우리는 이메일을 하나 더 받을 생각입니다. 이번엔 UserCreationForm 으로만 작 성하고 다음 시간에 추가해보도록 하겠습니다. 4) html 만들기 signup.html 자, 지금까지 우리가 만들진 않았지만 Django에서 만들어놓은 것, 아래와 같은 두 가지를 이용할 준비(?) 가 다 되었습니다. 1. User 모델 2. UserCreationForm 이제는 템플릿 파일을 직접 만들어 보겠습니다. 아래와 같이 만들겠습니다. <html> <body> <!-- Sign Up Form --> <form id="signup" method="post" action="{% url 'signup' %}">
  • 31. {% csrf_token %} {{ userform.as_p }} </form> </body> </html> 이렇게 만든 signup.html 을 프로젝트 최상위 디렉토리의 templates > registration 디렉토리 에 저장하겠습니다. {% url ‘signup’ %} urls.py에서 name이 signup으로 된 urlpattern으로 이동하라는 의미입니다. 이는 Django template language이며 url은 함수입니다. {% csrf_token %} Cross-Site Request Forgery라는 공격 방법을 막을 수 있도록 Django에서 미리 기능을 제공합니다. 사용 자가 값을 입력해주는 Form 태그 시작부분에 무조건 써줘야 에러가 나지 않습니다. {{ userform.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 이번엔 회원가입을 정상적으로 완료했을 때의 페이지를 만들겠습니다. 아래와 같습니다.
  • 32. [회원 가입을 완료한 후의 페이지] 이 페이지는 로그인할 수 있도록 링크만 했을 뿐 사용자에게 어떤 값을 입력받는 등의 기능은 없습니다. 예쁘게 옷을 덧입는 것은 다음 시간에 차차 하도록 하고 오늘은 기능 구현에만 집중하겠습니다. 아래와 같 이 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>
  • 33. 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
  • 34. from django.http import HttpResponseRedirect from django.core.urlresolvers import reverse from 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이라는 객체를 만들어라
  • 35. userform = UserCreationForm() return render(request, "registration/signup.html", { "userform": userform, }) 그리고 render 라는 함수를 이용해서 두 번째 인가값인 템플릿 파일에 세 번째 인값과 함께 렌더링해서 보내주게 됩니다. 이 세 번째 인자값에 바로 우리가 위에서 만든 userform 객체를 사전 객체로 보내줍니 다. POST 방식일 때 if request.method == "POST": userform = UserCreationForm(request.POST) if userform.is_valid(): userform.save() return HttpResponseRedirect( reverse("signup_ok") ) UserCreationForm클래스로부터 userform이라는 객체를 만들자! 먼저 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주소를 입
  • 36. 력해줍니다. 이 함수는 우리가 urls.py 에서 name으로 지정했던 URL을 의미합니다. return HttpResponseRedirect( reverse("signup_ok") ) 우리가 사용할 객체를 잊지말고 선언하자! 우리는 위에서 UserCreationForm , HttpResponseRedirect , reverse 라는 것을 사용했습니다. 이미 만들어져 있는 어떤 객체를 사용하기 위해서 이렇게 먼저 선언을 해주는 작업이 필요합니다. 꼭 잊지 말고 해줘야합니다. from django.http import HttpResponseRedirect from django.core.urlresolvers import reverse from django.contrib.auth.forms import UserCreationForm 4. URL 1) 회원가입 경로 설정 지금까지 우리는 아래의 것을 준비하였습니다. 1. User Model 2. UserCreationForm 3. 템플릿 파일 4. View 자, 이제는 마지막 하나가 남았습니다. 바로 사용자가 요청한 경로를 인식해 함수로 연결시켜주는 urls.py 입니다. 프로젝트와 이름이 같은 시작 패키지 디렉토리안에 urls.py 에 아래와 같이 작성하 도록 하겠습니다. urlpatterns = patterns('', # 중략, url(r'^signup/$', 'qna.views.signup', name='signup'), ) 위와 같이 사용자가 http://hostname/signup 경로로 접속했을 때 바로 옆에 인자값인 qna 앱의 views 모듈의 방금 위에서 만든 signup 함수로 연결해주는 역할을 합니다. 2) 회원가입 완료 후 페이지 경로 설정
  • 37. 하나 더 추가하겠습니다. 회원가입을 정상적으로 완료했을 때의 페이지를 보여줄 수 있도록 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'), ) TemplateView.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>
  • 38. 위에서 회원가입할 때와 비슷하게 생겼죠!? 우리는 로그인/로그아웃을 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
  • 39. [bitbucket.org 로그인 화면] 이제는 시대가 달라져서 다른 사이트에 가입했던 정보로 회원 가입과 로그인을 할 수 있게 되었습니다. 참 재미난 세상입니다. 1. OAuth(Open standard for Authorization) 이렇게 다른 앱을 통해 회원가입이 가능해진 이유가 OAuth라는 것 때문입니다. 2006년 11월, Ma.gnolia 에서 Twitter에게 OpenID에 대한 권한을 위임하면서 생겨났습니다. 본격적으로 2007년 4월 OAuth discussion 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으로 설치해주면 끝납니다
  • 40. 2) Setting settings.py settings.py 에서 설정해줘야하는 것은 아래에 있습니다. 1. INSTALLED_APPS에 항목 추가 새롭게 설치한 python-social-auth app을 추가합니다. 이제 새롭게 User socialauths 테이블에 생성되어 Thrid party로 가입한 사용자를 관리할 수 있습니다. 2. TEMPLATE_CONTEXT_PROCESSORS에 항목 추가 social.apps.django_app.context_processors.backends social.apps.django_app.context_processors.login_redirect 3. AUTHENTICATION_BACKENDS 새롭게 추가 인증 체계에 사용될 backend를 등록하는 항목 기본으로 django.contrib.auth.backends.ModelBackend python-social-auth의 facebook을 추가 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',
  • 41. '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' # Facebook SOCIAL_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’ ‘facebook’ 대신에 ‘google-oauth2’를 입력 2. in case of twitter url‘social:begin’ ‘facebook’ 대신에 ‘twitter’를 입력
  • 42. 필요에 따라 아래처럼 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. facebook 개발자 사이트에 접속합니다. 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번까지 하면 정상적으로 새로운 앱을 다 만든 것입니다. 화면을 다시 Refresh 하면 상단의 My Apps에 새롭게 생성된 앱이 보일 것입니다. 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. 정리
  • 43. 이렇게 Facebook에 앱을 등록하여 받은 key값으로 본인의 Django 사이트에 로그인을 할 수 있습니다. 위에 주석을 처리한 Google, Twitter 뿐만 아니라 Github, Google Plus 모두 가능합니다. 위 내용은 이 문서를 참고해서 작성했습니다. Written by initialkommit@Study-Bee.