TIL - Django (1)

Magit·2020년 4월 3일
0

TIL

목록 보기
12/16
post-custom-banner

What You Will Learn

✔️Django 과제 노션 가이드를 보고 레플릿 진행하기
✔️Django models, view, urls에 대해 이해하기
✔️httpie설치해서 사용해보고 어떻게 호출하는지 이해하기
✔️실습이 완료되면, 이후의 프로세스 진행하기.


main 디렉토리 내부 파일

  • views.py : 파일 이름만 봐서는 화면에 대한 파일로 보이지만, 로직을 담당하는 파일이다. 앞으로 장고프로젝트를 진행하면서 제일 많이 다루게된다. (함수형 view, 클래스형 view가 있는데, 클래스형 view를 더 많이 쓰게될것이다. 클래스를 안쓰면 정리가 힘들어진다. url을 심플하게 정의할 수 있다. as.view가 GET 이랑 POST를 라우팅할 수 있기에 클래스형을 쓰게된다.)
  • migrations 디렉토리 : models.py 파일에 정의한 테이블 구조를 manage.py의 makemigrations 옵션을 통해 생성되는 파일이 저장되는 디렉토리
  • models.py : 장고의 핵심 기능 중 하나인 ORM과 관련되어 있는 파일. 단순하게는 데이터베이스의 테이블을 정의하는 파일이라고 생각하면 좋다. 장고 ORM은 밑에 설명이 있다.
  • setting.py : 이름대로 프로젝트 관련 모든 설정 정보를 담고 있는 파일이다.
  • urls.py : 이름대로 url 경로에 대한 부분이다. blog.naver.com 에서 특정 사용자인 wecode를 표시라면 blog.naver.com/wecode 이다. 이런걸 바로 경로 라고 한다. url에서 특정 사용자의 블로그를 향하기 위해 지정된 사용자명으로 가기위해 설정하는 것이다. 이런 일을 하는게 urls.py 파일이다. 엔드포인트하고 엔드포인트 주소랑 연결해준다.
    • URLConf 파일(URL 부분을 정의해주는 부분)

repl.it 진행하기

1. 엔드포인트 만들어보기

# views.py
import json
    from django.views import View
    from django.http  import JsonResponse
    
    
    class MainView(View):
        def get(self, request):
    		    return JsonResponse({"Hello":"World"}, status=200)
# urls.py
from django.urls import path
    from .views  import MainView
    
    urlpatterns = [
        path('', MainView.as_view())
    ]
  • Run 클릭!

2. views.py와 urls.py

화면에 나온 {"hello":"world"} 는 바로 JSON이다.
JSON은 데이터 타입으로 JavaScript Object Notation의 줄임말로, 인터넷에서 자료를 주고받을 때 널리 쓰이는 데이터타입으로 자리 잡은 형식이다.

위에서 일어난 과정에서 사용된 부분들을 하나씩 설명해보자.

import json
from django.views import View
from django.http import JsonResponse

우리가 직접한 일은 아니지만 장고 프레임워크에는 내장된 모듈이 많이 존재한다.
그중에서 필요한 요소들을 적재적소에 import해서 사용하게된다.
이 과정에서 일반적으로 엔드포인트 뷰를 꾸릴 때, 항상 사용하게 되는 대표적인 요소들이 위에 기술된 코드들이다.

json : json 데이터를 처리하기 위해 import 한다.
View : View 클래스는 직접 생성하지 않고 장고 프레임워크에 내장된 클래스를 상속받아 쓴다.
JsonResponse : 서버에 요청에 대한 응답은 Json으로 응답하기 위해 사용한다.

class MainView(View):
    def get(self, request):
		    return JsonResponse({"Hello":"World"}, status=200)

위에서 작성한 클래스형 뷰 코드이다.
View 클래스는 우리가 작성한게 아닌 장고에 내장되어 있는 클래스이다.
View 클래스안에는 다양한 메소드가 존재하고 이는 우리가 장고를 사용하기 쉽게해준다.
def get 함수는 우리가 기술했지만, View 클래스에 내장된 메소드이다.
따라서 우리가 창조한 함수는 아닌것이다.
이름에서 보여주듯 이 함수는 HTTP 통신 메소드로 오는 호출에만 응답하게 되어있다.

그렇다면 GET 메소드는 어떻게 받을까?
답은 바로 urls.py에 있다.

from django.urls import path
from .views  import MainView

urlpatterns = [
    path('', MainView.as_view())
]

위 코드는 이전에 우리가 작성한 urls.py 파일의 코드이다.
첫번째 줄은 바로 장고에서 Url 경로를 처리하기 위한 모듈을 import 하는 코드이다.
두번째 줄은 우리가 작성해놓은 views 파일 안에 있는 MainView 클래스를 import 하는 코드이다.
장고에서 경로를 명시할 때, 항상 urlpatterns 와 가은 리스트 안에 경로를 저장하고 읽어들인다.

urlpatterns 안에 존재하는 코드를 읽어보면, ''일때 MainView.as_view() 즉 MainView라는 클래스에 내장된 as_view() 함수를 실행한다.
그럼 as_view() 메소드는 현재 주소인 나를 호출하면 그 호출을 한 http 메소드가 GET인지 POST인지 DELETE인지 UPDATE인지 등을 판별해서 그에 맞는 함수를 실행시켜준다.
위 부분은 아직 Http 통신에 대해 잘 모르겠다면 넘어가도되지만 알아둬야할 개념들이다.

여기까지가 Url 호출 그리고 urls 와 views에서 일어나는 일에 대한 설명이다.
다음은 모델을 정의하고 POST 메소드를 처리하는 엔드포인트를 작성할 것이다.


참조) Httpie

POST 메소드 처리를 위한 뷰를 제작하기 전에 http 메소드를 전송할 수 있는 프로그램인 Httpie를 설치하여보자.

ubuntu나 mac의 터미널에서 다음과 같이 실행해보자.

#Ubuntu
sudo apt install httpie

#Mac
brew install httpie
http -v 주소 복사

위 명령어로 해당 사이트를 확인할 수 있다.



3. models.py

modles.py 은 모델링과 관련된 파일이다.
아직 DB에 관해 배우지 않았지만 데이터를 서버에 저장하기 위해서는 Database가 필요하다.
장고에서는 우리가 별도로 DB 설치를 하지 않아도 SQLite3라는 파일기반의 경량화된 DB를 기보 제공하고 있다
따라서 장고를 설치해서 사용하는 것만으로도 사용할 수 있는 DB가 존재하고 이를 장공서 컨트롤하기위해 장고는 ORM이라는 것을 제공하고 있다.

ORM (Object Relational Mapping, 객체-관계 매핑)
객체와 관계형 데이터베이스의 데이터를 자동으로 매핑(연결)해주는 것을 말한다.
객체 지향 프로그래밍은 클래스를 사용하고, 관계형 데이터베이스는 테이블을 사용한다.
객체 모델과 관계형 모델 간에 불일치가 존재한다.
ORM을 통해 객체 간의 관계를 바탕으로 SQL을 자동으로 생성하여 불일치를 해결한다.
데이터베이스 데이터 <--매핑--> Object 필드
객체를 통해 간접적으로 데이터베이스 데이터를 다룬다.

이와 같이 ORM을 사용하면서 원하는 모델을 작성하고 다루는 곳이 바로 models.py 파일이다.
쉽게 말하면 DATABASE를 잘 몰라도 models.py 를 통해서 DB를 관리할 수 있다는 사실이다.

이제 모델을 생성해보자.
먼저 User정보를 담는 테이블을 작성해보자.
보통 우리는 회원가입시에 name, email, password를 받는다.
또 언제 가입했는지 혹은 언제 회원정보를 수정했는지 알기 위해 시간 정보를 저장한다.

from django.db import models


class Users(models.Model):
    name       = models.CharField(max_length = 50)
    email      = models.CharField(max_length = 50)
    password   = models.CharField(max_length = 300)
    created_at = models.DateTimeField(auto_now_add = True)
    updated_at = models.DateTimeField(auto_now = True)

위와 같이 작성하고 별 이상이 없다면 장고는 models.py 파일을 참고해서 migrations 및 migrate를 하는데, 레플릿 환경은 작성된 파일에 문제가 없다면 자동으로 진행된다.
별다른 문제없이 페이지가 나오고 있다면 잘 진행된것이다.

모델을 만들었다면, 남은 일은 뷰에서 모델에 정보를 가져오거나 정보를 입력할 수 있도록 하는 일이 남아있다.
이전에 작성했던 view파일에 변화를 줄 시간이다.

import json
from django.views import View
from django.http  import JsonResponse
from .models      import Users


class MainView(View):
    def post(self, request):
        data = json.loads(request.body)
        Users(
              name     = data['name'],
              email    = data['email'],
							password = data['password']
        ).save()
        
        return JsonResponse({'message':'SUCCESS'}, status=200)

    def get(self, request):
		    return JsonResponse({"Hello":"World"}, status=200)

이전에 작성한 MainView 클래스에 post 함수를 추가했다.
이렇게되면 우리는 위에서 만든 Users라는 모델에 데이터를 입력할 수 있는 로직을 만들것이다.

http -v '본인 레플릿 페이지 주소' name='테스트용이름' email='테스트용이메일' password='비밀번호'

나는 여기서 CSRF cookie not set 이라는 에러 메세지가 떴다.
검색해서 참조할만한 답변을 확인해봤다.
wecode - Stackoverflow
에러 메시지를 보시면 CSRF cookie not set 이라고 되어있습니다. CSRF는 Cross Site Request Forgery의 약자 입니다. CSRF는 이름 그대로 실제 사이트가 아닌 모방 사이트 혹은 가짜 사이트에서 브러우저의 유저 로그인 세션을 이용하여 마치 실제 유저가 행하는것처럼 액션을 서버에서 실행되게 만드는 해킹 공격 입니다. 그래서 장고에서는 디포트로 CSRF 를 방지해줍니다. 그래서 CSFR token 이란걸 매 POST 요청마다 체크하게 되어있습니다.


다만, REST API에서는 CSRF Protection이 크게 의미가 없습니다. 왜냐하면 django의 유저 로그인 세션 기능을 사용하지 않기 때문입니다. REST API의 경우 일반적으로 JWT(Json Web Token) 이라는 걸 대신 사용합니다.


그럼으로 REST API 개발의 경우 CSRF Protection을 비활성화 해주면 됩니다. 비활성화 하는 방법은 다음과 같습니다. 프로젝트의 settings.py 파일에서 MIDDLE_WARE 설정에서 django.middleware.csrf.CsrfViewMiddleware 요소를 지워주면 됩니다. CsrfViewMiddleware 가 CSRF Protection을 실행하는 미들웨어 임으로 지워주면 더이상 CSRF token 체크를 하지 않게 됩니다.


에러가 난다면 settings.py 에서 다음과 같이 주석처리해주면 된다.


성공하면 나오는 화면이다.

방금 일어난 일은 바로 HTTP통신중 POST 메소드를 구현해봤다.
바로 데이터베이스에 데이터를 입력했다는 의미이다.
그럼 입력된 값은 어떻게 확인할 수 있을까?
바로 기존에 작성한 GET메소드를 수정하면 된다.

   def get(self, request):
        user_data = Users.objects.values()
		    return JsonResponse({'users':list(user_data)}, status=200)

위와 같이 기존의 get함수를 변경해주자.
정상적으로 데이터가 입력됐고, 메소드 변경이 잘 이뤄졌다면 이제 레플릿의 경우는 결과창에 결과가 뜬다.

만약에 실제로 운영되는 서버라면 password 항목이 암호화가 되어있어서 이렇게 입력값이 나오진 않는다.
여기까지가 엔드포인트 기초과정이다.

수업 듣다가 적어놨던 추가정보

manage.py가 있는곳이 루트 디렉토리이다.
python manage.py 라고 치면 이용할 수 있는 명령어를 알 수 있다.


show nanage.py showmigrations
manage.py sqlmigrate users 0001


runserver : 서버 돌리고 앤드포인트 테스트
makemigrations 와 migrate의 차이점 알아보기
makemigrations : 클래스에 코딩해놓은 테이블 구조 기반으로 장고에서 쓸 수 있게 이 자료를 따로 메타 데이터로 만드는것
migrate : 디비에 실제 크리에이트 테이블로 테이블을 만든다.

Http 통신에 대해서 정리해보기

profile
이제 막 배우기 시작한 개발자입니다.
post-custom-banner

0개의 댓글