Django - 기본적인 app 생성해 json 출력해 보기 (1)

solee·2022년 2월 16일
2

Django

목록 보기
4/12
post-thumbnail

기존에 진행하던 튜토리얼은 part.3을 작성하는 중인데, 생각보다 글이 너무 길어지고 할것은 쌓여서 작성하던 투표 대신 더더욱 기본적인, 내가 입력해둔 데이터를 출력하는 앱에 대해 작성하려고 한다. 어느 정도는 튜토리얼과 겹칠 것이다.
가상환경을 생성하는 1번부터 시작해 httpie를 통해 입력한 명령어로 데이터를 추가하는 것까지가 목표다.



django는 ORM이라는 것을 사용하는데, 이것은 SQL 명령어를 직접 입력하지 않고 ORM을 대신 사용해 데이터베이스에 접속해 명령을 수행할 수 있게 한다. insert, update, delete 등등을 SQL 명령어 없이 수행할 수 있는데, SQL에 아직 더 익숙해서 그런지 아직 '굳이...?'라는 생각을 하게 된다. 과연 내가 이 글을 다 작성한 다음에는 다르게 말할 수 있을지 궁금하다.




1. 초기 세팅

1) 가상환경, 데이터베이스 설정

먼저 패키지를 관리할 때 각각의 패키지를 독립적으로 관리, 사용할 수 있도록 가상환경을 생성한다. miniconda3을 사용한다.

conda create -n gs25 python=3.9
conda activate gs25

gs25라는 가상환경을 생성하고 activate한다. 엄청난 팬은 아닌데 꽤나 팬이다.

테마를 사용하기 때문에 오른쪽에 보이는 표시로 어떤 가상환경을 사용중인지 알 수 있다.



그리고 mysql에서 데이터베이스를 생성한다. 이 데이터베이스에 내가 사용할 테이블들을 models를 이용해 생성하고 사용할 것이다.

# mysql에서
create database gs25 character set utf8mb4 collate utf8mb4_general_ci;

데이터베이스의 이름도 동일하게 설정한다.




2) 가상환경에 장고 설치 및 프로젝트 생성

pip install django
pip install mysqlclient

장고는 그냥 설치되는데, mysqlclient은 mysql을 start해야 설치할 수 있으므로 에러가 발생하면 먼저 mysql이 깔려있는지, 그리고 잘 로그인되는지 확인한다.

# 만일 WSL2를 사용중인데 mysqlclient가 설치되지 않는다면 아래 명령어들을 이용한다.
sudo apt-get update
sudo apt-get upgrade
sudo apt-get install python3-dev default-libmysqlclient-dev build-essential
pip install mysqlclient

잘 설치됐으면 위 사진처럼 될 것이다.


여기까지 설치됐으면 이제 django project를 생성한다.

django-admin startproject gs25




3) settings.py 설정

startproject를 하면 해당 이름으로 디렉토리가 생성된다. 디렉토리 내부는 다음과 같다.

gs25라는 디렉토리 안에 manage.py와 또다른 gs25디렉토리가 있다. 또다른 gs25, 즉 하위 디렉토리에는 settings.py나 urls.py가 보인다. settings.py를 열어보자.

ALLOWED_HOSTS = ["*"]

INSTALLED_APPS에서 사용하지 않을 admin, auth를 주석처리하고 
MIDDLEWARE에서도 CsrfViewMiddleware와 AuthenticationMiddleware를 주석처리한다.

보안을 위해 DATABASES와 SECRET_KEY를 settings.py에서 제거한다. 지금은 git에 올리지 않을 거지만, 이 두 키를 상위 디렉토리인 gs25, 즉 manage.py가 있는 위치에 my_settings.py같은 이름으로 파일을 생성한 후 저장한다. 파일 안에는 다음과 같이 작성한다.
# my_settings.py
DATABASES = {
    'default' : {
        'ENGINE': 'django.db.backends.mysql',
        'NAME': 'gs25', # 아까 생성한 DB명
        'USER': 'root',
        'PASSWORD': '', # mysql 비밀번호
        'HOST': '127.0.0.1',
        'PORT': '3306',
    }
}

SECRET_KEY = 'django-insecure-%u)td=4~~~~'

SECRET_KEY도 settings.py에서 걸러내 위와 같이 작성하고, settings.py는 아래처럼 저장한다.

from my_settings import SECRET_KEY, DATABASES

SECRET_KEY = SECRET_KEY
DATABASES = DATABASES



하위 디렉토리 gs25에서 urls.py를 열어 기본적으로 설정되어 있는 url을 삭제한다. 그러면 결과가 다음처럼 된다.

from django.urls import path

urlpatterns = [
]



그 다음에는 corsheaders를 설치한다. 이건 CORS, 즉 Cross Domain 이슈때문에 설치해 주는 것인데, 도메인이나 포트넘버가 다른 서버의 자원을 요청하기 위해 필요한 라이브러리다.

pip install django-cors-headers

터미널에서 설치해 준 후 settings.py의
INSTALLED_APPS에 'corsheaders'를,
MIDDLEWARE에는 'corsheaders.middleware.CorsMiddleware',를 추가해 준다.

그 후에는 settings.py에

##CORS
CORS_ORIGIN_ALLOW_ALL=True
CORS_ALLOW_CREDENTIALS = True

CORS_ALLOW_METHODS = (
    'DELETE',
    'GET',
    'OPTIONS',
    'PATCH',
    'POST',
    'PUT',
)

CORS_ALLOW_HEADERS = (
    'accept',
    'accept-encoding',
    'authorization',
    'content-type',
    'dnt',
    'origin',
    'user-agent',
    'x-csrftoken',
    'x-requested-with',
)

를 추가해 corsheaders를 사용할 수 있도록 설정한다.



마지막으로 APPEND_SLASH를 설정해 주는데, 이것은 url에 자동으로 /를 붙여준다. 기본값이 True인데 False로 해야 한다. 수정하는 게 아니므로 추가해 준다. 이것으로 url을 세팅할 때 /를 원하는 위치에 붙일 수 있다.

APPEND_SLASH = False



python manage.py runserver 8080

서버가 잘 돌아가는지 확인하면 세팅은 마무리된다. 나는 윈도우라 8080을 붙였다.




git같은 경우 이 디렉토리는 복습 겸 작성하는 것이므로 생략한다.




2. App 생성

지금까지 생성한 것은 프로젝트였다. 이제는 app을 생성해 내가 원하는 기능을 구현해 본다. 물론 지금은 기능을 구현할 것은 아니고 데이터를 삽입하고 출력하는 간단한 기능을 만들 것인데, django가 가진 MTV 패턴의 템플릿은 이용하지 않고 httpie를 이용해 데이터를 전송할 것이다.

python manage.py startapp snack

아까는 startproject고 이번에는 startapp이다. 이 명령어를 실행하면 snack이라는 디렉토리가 생성된다. 그 구성은 다음과 같다.

끔찍한 초록색은 무시하자... (백엔드 지망이지만 나도 눈이 있다)
아무튼 확인해 보면 snack이라는 디렉토리가 생성되었고 그 안에는 admin, apps, models, tests, views라는 파일들이 있다. 그리고 migrations라는 디렉토리에 init파일이 보인다.

MTV패턴을 기준으로 생각해 보면, 모델과 뷰가 여기 있는 것이다. 모델은 아까 생성해서 연결한 데이터베이스에 데이터를 어떻게 저장할 것인가에 대해 정의하고 있으며 뷰는 그것을 어떻게 연결하고 표현할지에 대한 비즈니스 로직을 가지고 데이터를 가공한다. 아까도 언급했듯이 템플릿은 사용하지 않고 데이터를 직접 보내줄 것이다.


아무튼, app을 생성했으니 하나 기억나면 참 좋다.
바로 settings.py에 있던 INSTALLED_APPS 이다!! app을 생성한 후에는 반드시 설정 파일에 등록해 앱을 읽어올 수 있도록 한다.

	# INSTALLED_APPS에 추가한다
    'snack', 




3. Models 작성

새로 생성된 앱의 snack 디렉토리에서 models.py를 작성한다.
테이블은 class라는 형태로 정의된다.

작고 귀여운 예시를 살펴보자.

gs25에 간식들을 판매하는데, 특정 상품은 특정 카드로 할인받을 수 있다. 예를 들어 칸쵸는 신한카드와 롯데카드로 결제하면 할인이 되고, 홈런볼은 롯데카드와 카카오뱅크카드로 결제하면 할인이 된다. 이것을 manytomany 관계, 다대다 관계라고 할 수 있을 것이다.


snacks_cards 테이블이 양 테이블의 id를 참조하며 중간 테이블로 기능한다.
그러면 이 테이블을 model에 작성한다.


먼저 눈에 띄는 것은 class다. 각 테이블이 class로 구현되고 models.CharField() 등 타입을 지정해 변수를 컬럼으로 삼는다.

  • id는 자동으로 생성되는 것이기 때문에 기재하지 않는다.

  • class Meta를 사용해 데이터베이스에 적용될 테이블의 이름을 설정할 수 있다. class는 대문자로 시작해 단수를 사용하고 table명은 소문자이자 복수형을 사용한다.

  • 외래키는 ForeignKey()를 사용해 어떤 테이블과 연결되는지, 또 어떻게 설정할지(Null, Cascade 등) 정보를 인자로 전달한다.


그리고 ManytomanyField()가 있다.

  • 다대다 관계에서 한쪽 테이블에 m2m을 명시한다. 이는 컬럼으로 적용되는 것이 아니며 through를 사용해 중간 테이블을 명시해 참조할 수 있다.

manytomany에 대해서는 먼저 이 프로젝트를 마무리한 후 따로 설명할 것이다.



이렇게 models를 작성한 후에는 이 내용을 데이터베이스에 적용해 테이블을 생성해야 한다.
그러기 위해서는 두 단계가 필요하다.

python manage.py makemigrations snack

먼저 makemigrations다. 이 명령어는 models에서 파일을 읽어들여 데이터베이스에 테이블을 생성하기 위한 일명 '설계도'를 작성한다. 뒤에는 snack이라고 앱의 이름을 적어줘도 되고 적지 않아도 된다. 적지 않을 경우 프로젝트의 모든 app의 models파일을 읽어들인다.
무사히 migration을 생성하면 아래와 같은 결과가 출력된다.

여기서 보이는 0001_initial.py가 바로 생성한 설계도 파일이다. snack 디렉토리 안에 migration 디렉토리에 생성된다.


그 다음에는 이 migration 파일을 migrate한다.

python manage.py migrate

migration이라는 설계도로 데이터베이스에 테이블을 생성한 것이다.


그러면 mysql에 접속해 보자.

use [테이블명] 명령을 사용해 어떤 데이터베이스를 사용할지 선택한 후 tables를 확인하면 models에 작성한 클래스들이 테이블이 되어 무사히 생성된 것을 확인할 수 있다.

테이블의 컬럼과 속성 등을 확인할 수 있고, select문을 사용해 데이터도 확인할 수 있지만 아직 데이터를 넣지 않았으므로 비어있다.






이제 어떻게 하면 될까? 모델이 생성되었으니 데이터를 삽입하면 될까?
아니, 아직이다.
왜냐하면 아직 더 중요한 게 남아있기 때문이다.

django가 MTV패턴을 사용하고 Template는 사용하지 않겠다고 했다. 지금은 Model을 작성했다. 그러면 뭐가 남았을까?




4. Views 작성

아까와 마찬가지로, 생성된 app 디렉토리의 views.py에 작성한다. 또 아까와 마찬가지로, class를 작성한다.

그런데 뭘 작성해야 할까? models에서 정의한 테이블에서 데이터를 삽입하거나 꺼내오는 작업을 할때 views에서는 데이터를 로직에 따라 가공한다. 그러니 프론트에서 서버에 보내는 "데이터"를 받아 데이터베이스에 삽입하거나, 프론트에서 들어오는 요청에 따라 "데이터"를 꺼내서 전송해야 할 것이다.



1) 데이터 삽입하기: POST

처음에는 꺼낼 데이터가 없으니 데이터를 전송 및 삽입하는 것부터 시작해보자.

"데이터"를 데이터베이스에 삽입한다는 것은 mysql에서 insert를 한다는 것과 같다. 그러니 django에서 ORM이 어떻게 insert를 하는지를 알아야 한다.

놀랍게도 아주 간단하다!

아주 간단하게만 보여준다면, 다음과 같다:

Snack.objects.create(name="홈런볼")

Snack이라는 클래스에, create한다. name은 "홈런볼"이다.
이게 뭐야 싶을 정도로 간단하다.

이제 조금 자세하게 보여준다면, 다음과 같다:

맨 위부터 보자.

  • json을 import한다.

  • http와 views를 import한다.

  • 사용할 models에서 class를 import한다.

이렇게 세 번의 import가 있다. 먼저 json을 보자.

프론트와 백단이 http로 통신할 때에는 json을 사용해 데이터를 주고받는다. json이란 딕셔너리와 비슷한 형태를 가지고 있는데, key값과 value값을 가진다.

{
    "name" : "김개발",
    "age" : 31,
    "email" : "devdevkim@gmail.com"
}

그리고 class를 보자. SnacksView라는 이름의 View를 작성하였다. 그 안에는 def post가 있다. http를 아는 사람이라면 어! 할 것이다.

  • 함수의 이름은 http의 method를 따른다. 그를 통해 post로 요청이 들어오면 함수 post가 작동하고 get으로 요청이 들어오면 함수 get이 작동하는 원리다.

  • 함수 post는 인자를 두 개 가지는데, 두 번째 인자로 REQUEST를 가진다.

이 request란 서버로 들어온 데이터를 말하는데, 11번째 코드를 보면 json형태로 전송된, request의 body에 들어 있는 데이터를 data라는 변수에 저장한다.
이때, 전송받은 데이터는 json이지만 data는 dictionary다.

# 전송받은 데이터 : json
request.body : { "name": "김개발", "age": 31 }

# 변환한 데이터 : dict
data = { "name": "김개발", "age": 31 }

그러면 이 다음 13번 코드를 보자. 아까 본 그 친구다!
그러나 이번에는 아주 조금 다른데, name=" "에 data["snack_name"]이라는 것이 있다. 이 녀석은 무얼 하는 녀석일까? 바로 위에서 data는 dict라고 했다. 바로 data에서 key 값이 "snack_name"인 것을 찾아 name에 할당하는 것이다!
name에 전송받은 데이터 중 key 값이 "snack_name"인 값을 담아 create하면 데이터베이스에 해당 값이 들어간다.

그 후에 마지막 15번 코드를 보자.
JsonResponse로 설정한 메시지인 {"message":"created"}와 201이라는 status를 리턴한다. 프론트에서는 서버로 {"name": "홈런볼"}을 전송한 후 성공했다는 의미로 created라는 답을 받는 것이다.

하지만 아직 끝이 아니다. 데이터를 삽입하기 위해서는 아직 할 일이 조금 더 남아 있다.
그 전에, 데이터를 삽입했으니 데이터를 출력해오는, 자원을 끌어오는 방법에 대해 설명하자.




2) 데이터 출력하기: GET

데이터를 삽입했으면, 이제 그 데이터를 꺼내 볼 차례다. view가 하는 일인, 프론트에서 들어오는 요청에 따라 "데이터"를 꺼내서 전송하는 것이다.

데이터를 출력하는 것은 삽입하는 것보다는 조금 까다롭다. 하지만 기본적인 구조는 같다.

얘도 간단하다! 아주 조금 덜.

이미지에는 없지만 아까의 post와 같은, SnacksView에 작성한 또 다른 함수다.

results라는 리스트가 있고, Snack.objects.all() 로 Snack 클래스의 모든 데이터를 snack_list에 담았다. 이 리스트는 쿼리셋QuerySet의 형태로 출력된다. QuerySet에는 각각의 데이터의 객체가 저장되어 있다.

for문에서 리스트 results에 append하는데, 그 형태는 json과 같다(물론 우리가 가공할 때에는 dict이다).

results.append({
	"id":i.id,
	"name":i.name
})

i.id에서 어라? 해야 한다.
Snack.objects.all()과 기시감이 느꺼지지 않는가?

snack이라는 클래스(테이블)에서 꺼낸 전체 리스트(Snack.objects.all())에서 꺼낸 i라는 하나의 객체에서 id를 꺼내 "id"라는 키의 값으로 할당한다. 또 name을 꺼내 "name"이라는 키의 값으로 할당한다. 그 후에 이 값을 JsonResponse를 통해 json의 형태로 프론트에 전송하는 것이다.



그러면 드디어!!! 데이터를 삽입하자!






는 아직 아님ㅋ

5. GET - url 연결 및 접속

자, 우리는 데이터베이스를 정의하는 Model을 작성했고, 데이터를 가공하고 비즈니스 로직을 선언한 View를 작성했다. 이제 (생성한 템플릿은 없지만) django가 생성해주는 사이트에서 내가 요청한 정보를 꺼내올 차례다.

어디서 꺼내온다고?
사이트.

그럼 이제 의문이 든다.

어디로 접속하는데?


사이트로 접속하려면 뭐가 필요할까? 당연히 url이다. 내가 어디로 접속하려고 하는지, 인터넷은, http는 내가 요청한 url을 통해 연결해 주겠지.

디렉토리의 트리를 보자.

눈에 띄는 게 있다.
있어야 한다!

gs25라는 하위 카테고리에, urls.py라는 파일이 있다! 열어 보면 다음과 같다.

urlpatterns가 비어 있는데, 1-3에서 기본 페이지로 연결되어 있던 것을 지웠던 걸 기억할 것이다. 기본적으로 사이트(http://127.0.0.1:8080/)로 연결되는데, 여기서 이 urlpattern을 통해 어떤 페이지로 접속시킬지를 연결해주는 것이다. 이것을 URLConf라고 한다.

주석처리된 글을 보면 뷰의 형태에 따른 여러 방법을 소개하고 있는데, class-based views처럼 연결할 것이다.

하지만 그게 여기는 아니다. 이미지의 디렉토리 경로를 보자. gs25의 gs25디렉토리에 있는 url이다. 여기에서는 우리가 추가한 snack이라는 app으로 연결할 수 있도록 해야 한다.
그러니 이렇게.

include를 import하고, snack이라는 path가 들어온다면 snack.urls 에서 찾으라는 뜻이다.
http://127.0.0.1:8080/snack/1 이라면 snack까지만 경로를 확인하고, /1을 판별하기 위해 snack.urls로 가라는 거다. 그런데 어라? 아까의 tree를 다시 보면 snack의 어디에도 urls.py가 없다.

그러면 어떻게 해야 할까?
만들어주면 된다!


snack에 urls.py를 생성하고, 다음과 같이 작성하자.


path는 그대로인데, snack 디렉토리에서 views라는 파일을 찾아 거기에서 SnacksView를 import하고 있다. 그리고 바로 urlpattern에서 아까 주석처리된 부분에 있던 표현인 SnacksView.as_view()를 사용하는 것을 확인하자.


그러니 http://127.0.0.1:8080/snack/snack 이라는 경로가 있다면, 첫 번째 http://127.0.0.1:8080/snack/ 까지의 경로로는 snack이라는 앱으로 연결이 되고, snack.urls.py에서 남은 /snack이라는 경로가 나를 SnacksView로 연결해준다.

중요한 것! 경로를 지정할 때 슬래쉬에 매우! 유의해 준다.
설정에서 APPEND_SLASH를 False했으므로 자유롭게 붙일 수 있지만

서버를 열고 링크에 접속해보면?

짜잔! results가 보인다! 아직 아무 데이터도 없어서 비어 있지만, 5-2에서 작성한 GET 함수가 응답으로 내어준 result임을 확인할 수 있을 것이다.

서버를 구동중인 터미널에서 아래와 같은 메시지를 확인할 수 있다.

노란색으로 칠했지만, GET 메서드로 /snack/snack 에 접속해 200이라는 status를 전달했음이 보인다.






6. POST - 테이블에 데이터 삽입

이제 즐겁게 GET 메서드를 사용했다. 그러면 먼저 작성했던 POST는 어떻게 사용할 수 있을까? POST란 데이터를 서버에 전송하는 메서드로, 단순히 링크만 가지고 주소창에 입력해 접속할 수 없다. 반면에 GET은 데이터를 요청하는 메서드로 view에서 지정한 데이터를 요청하기 때문에 단순히 링크로 접속하면 데이터 없이 GET으로 request가 들어간다.

그러면 POST로 접속하고 싶다면??
다시 말하자. django의 ORM을 사용해 생성한 테이블에 데이터를 삽입하려면?


insert문을 사용할 수도 있지만, 두 가지 방법이 있다.

  • httpie로 서버에 http request를 보내며 전송하는 방법

  • python shell에서 하드코딩하는 방법

먼저 httpie를 사용해 보겠다.


1) httpie를 사용한 데이터 삽입

아까도 확인했지만, 프론트와 백단이 통신할 때에는 json을 사용해 데이터를 주고받는다. json는 딕셔너리와 비슷한 형태를 가지고 있는데, key값과 value값을 가진다.

{
    "name" : "김개발",
    "age" : 31,
    "email" : "devdevkim@gmail.com"
}

이 데이터를 서버로 전송하기 위해서는 어떻게 해야 할까? httpie로 서버에 request를 보내겠다고 했다.
먼저 httpie라는 놈을 설치해 줘야겠지.

sudo apt install httpie

우분투를 사용함을 다시 언급하겠다. 맥은 brew를 사용한다.



그 다음에는 터미널에 아래처럼 요청을 보내면 된다.

http -v POST 127.0.0.1:8080/snack/snack snack_name="홈런볼" 

이때 링크 뒤에 붙여서 보내는 정보에 주의하자! 여러 정보를 보내도 ,는 사용하지 않고, 또 view와 통일시켜야 한다. 무슨 뜻이냐면, view를 다시 보자.

여기서 보내는 정보들을 data에 담았다. 그리고 create 구문에서 data 중에 키가 snack_name인 것을 name에 담아 삽입했다.
만약 요청을 이렇게 한다면?

# 틀린 요청!
http -v POST 127.0.0.1:8080/snack/snack name="홈런볼" 

name이라는 정보를 view에서 꺼내지 않으므로 key값을 찾을 수가 없어진다! KeyError가 발생해 프로그램이 종료되고 서버가 터졌다는 500에러가 발생할테니 건강에 좋지 않다.


아무튼 문제가 없다면?
짜잔.

에러가 없다면(보통 urls.py나 요청하는 key에 문제가 많이 생긴다. 나도 알고 싶지 않았다...) view에서 리턴하도록 설정된 메시지가 리턴된다.

그러면 이제 데이터가 잘 들어갔는지 확인해 보자. 아주 간단하게는 아까 접속한 링크인 http://127.0.0.1:8080/snack/snack 에 다시 접속하면 된다.

요로코롬~




꽤나 만족스럽다.
그러나? 나는 아직 배고프다!!!

금방 사용한 httpie는 그러면 POST에만 사용할 수 있는 걸까? 전혀 아니다.

http -v GET 127.0.0.1:8080/snack/snack 

이렇게 요청을 보내면, 같은 페이지에 GET 요청이 들어가는 것이다.

results가 무사히 리턴되는 걸 확인할 수 있다.






2) python shell에서 하드코딩으로 데이터 삽입

httpie를 사용한 방법은 정확히는 서버에 멀쩡하게 요청을 보내 내가 작성한 models와 views를 사용하는 방법이다. 하지만 그 대신 데이터를 깡으로 집어넣고 싶다면 이 방법을 사용하면 된다.

manage.py가 있는 위치로 이동하자.

그리고 명령어.

python manage.py shell

mysql에 접속한 것처럼 화면이 바뀌었다. django 튜토리얼에서 q.Question 등으로 질문과 답변을 입력해 준 것처럼(api 실험해보기를 참고), gs25라는 프로젝트의 snack에도 같은 일을 할 수 있다.

방법은? 전혀 어렵지 않다. 아까 views에서 사용한 그 방법 그대로다!
다만 한 가지 신경써 줘야 한다.

models에서 Snack 클래스를 import하고 냅다 출력해 보았다.
아직 데이터가 1개뿐이라 출력되는 것이 1개뿐이지만, 결과물이 조금 다른 것을 확인할 수 있을 것이다.

Snack.objects.all()
Snack.objects.get(id=1)
Snack.objects.filter(id=1)

먼저 첫 번째 .all()은 말 그대로 Snack 클래스(이자 테이블)에 있는 모든 데이터를 꺼내온다. 결과물은 QuerySet이다.

두 번째 .get(id=1)은 id가 1인 결과물 1개를 찾아온다. 이것은 결과물이 QuerySet이 아니라 객체임을 볼 수 있다. .get()같은 경우 결과물을 1개만 가질 수 있으므로 만일 결과물이 1개 이상 반환된다면 에러가 발생한다.

세 번째 .filter(id=1)은 get과는 다르게 QuerySet을 반환한다. 결과물은 1개 이상 반환될 수 있으며 ()안에 아무것도 입력하지 않는다면 all()과 동일하게 작동한다.


반환된 결과물이 QuerySet이건 아니건 결국은 객체를 받는다는 것이 중요하다. 한번 get()으로 반환받은 결과물을 다른 변수에 저장해 보자.

자! 아까 우리가 view에서 작성한 것들이 이해되는가?
sss에는 id가 1인 Snack의 객체가 저장되어 있고, sss.name과 sss.id를 사용해 해당하는 컬럼의 데이터를 꺼낼 수 있다!


그럼 같은 방식으로 데이터를 삽입할 수 있다는 것도 이해할 수 있을 것이다.

Snack.objects.create("키"="값") 으로 데이터들을 조금 더 넣어주었다. filter()과 all()은 동일하게 전체 QuerySet을 반환한다고 했다.

그럼 여기서 데이터를 꺼낼 땐 어떻게 해야 할까? 또다시 변수에 담아 보자.

kkk에 담은 쿼리셋에서 kkk.name을 출력하려고 했다. 그러자 에러가 발생한다. 그리고 메시지를 읽어 보면 QuerySet에는 name이라는 속성이 없다고 한다.
아까 QuerySet이 무엇이라고 했지? 리스트 같은 것이라고 했다. 그냥 리스트를 사용할 때에도 우리는 인덱싱을 사용한다!

그러므로 해야 하는 일은 다음과 같다.

오케이.

이제 다시 아까의 링크로 접속해보면, 추가한 데이터들이 보인다.




마치며

여기까지가 일단 데이터를 삽입하고 요청하는 django의 아주아주아주 가장 기초적이고 간단한 app을 생성, 사용하는 것이다.

글을 시작할 때에 ORM에 익숙해질 수 있을까 했는데, 익숙하긴 한데 역시 아직 SQL이 더 좋은 것 같다. insert할 때 key(컬럼명)을 하나하나 적어줘야 하는 것도 그렇고... ORM에도 그런 방법이 있을 것 같은데 알게 되면 그것도 포스팅해야지.


언급은 안 했는데, 누군가는 알 것 같다. "아까 model에 작성한 나머지 두 클래스는 어디로 갔을까?"

간식을 할인받을 수 있는 정보들, CardSnack_card 말이다!
이것들에 대해서는, 즉 ForeignKey와 Manytomany에 대해서는 다음 글에서 마저 작성하도록 하겠다.




profile
DA DA DA

0개의 댓글