장고를 튜토리얼부터 배우고 있는데 아직 모르는 것 투성이다.
따라는 하는데 이해가 안된다. 그렇다면 이해를 하기 위해 무엇부터 공부해야할까?
문득 '모든 언어는 단어에서부터 시작한다'라는 생각이 들었다.
단어의 뜻을 알아야 문장의 의미를 유추할 수 있다. 의미를 유추하면 그제서야 맥락이 보이기 시작한다.
그렇다면 지금 내가 해야할 것은 장고와 관련된, 특히 자주 쓰이는 용어들의 의미를 파악하는 것이다.
이 글은 생소한 용어들을 하나씩 정리하면서 앞으로 내가 장고를 이해하는데 도움이 되어줄 글이다.
앞으로 주기적으로 업데이트 하면서 새로운 용어는 추가하고 잘못알고 있었던 것을 수정할 예정이다.
<2021.11.11>
URLconf (파일명 : urls.py)
- 클라이언트로부터 요청을 받으면 가장 먼저 요청에 들어있는 URL을 분석
- 요청에 들어있는 URL이 urls.py 파일에 정의된 URL패턴과 매칭되는지 체크
- URL 매칭을 확인하면 View를 호출함 (호출 시 HttpRequest 객체와 매칭할 때 추출된 단어들을 뷰에인자로 넘겨줌)
- '<>' 를 Path Converter 라고 부름. 이 안에는 여러가지 타입 사용가능(str, int, path, 등)
<예시>
from django.urls import path
from . import view
urlpatterns = [
path('articles/2003/', views.special_case_2003),
path('articles/<int:year>/',view.year_archive),
]
- articles/2003/ 부분 : URL
- views.special_case_2003 부분 : 처리 함수(뷰)
View (파일명 : views.py)
- View는 필요한 데이터를 모델 (혹은 외부)에서 가져와서 적절히 가공하여 웹 페이지 결과를 만들도록 컨트롤하는 역할
- views.py 파일 내, 각 함수가 하나의 View를 정의한다. 각 View는 HTTP Request를 입력 파라미터로 받아들이고, HTTP Response를 리턴한다.
from django.http import HttpResponse
위의 예제는 하나의 View 함수를 표현한 것인데, 이 함수는 입력으로 항상 request 를 받아들이고, response 를 리턴하게 된다. View는 (1) 웹페이지 내용을 갖는 HttpResponse 객체를 리턴하거나 (2) Http404 같은 Exception을 리턴한다. 여기서는 간단한 HTML Text를 포함한 HttpResponse() 객체를 리턴하고 있다. 일반적으로 Django 에서는 좀 더 복잡한 HTML을 처리하기 위해 뷰 템플릿(Template)을 사용한다.
또 다른 예제로서 아래는 Http404 Exception을 일으키는 것을 예시한 것으로 return이 아닌 raise를 사용함에 주목하자. 비슷한 효과를 내기 위해 HttpResponseNotFound를 사용할 수 있지만, Http404이 좀 더 편리한 기능이다.
from django.http import Http404, HttpResponseNotFound
*raise 로 예외를 발생시키면 raise 아래에 있는 코드는 실행되지 않는다.
참고 : https://dojang.io/mod/page/view.php?id=2400
Model (파일명 : models.py)
- model.objects의 method를 통해 데이터베이스와 통신하는 곳
- QuerySet API가 제공하는 매서드를 활용하여 데이터베이스에 데이터를 생성/조회/수정/삭제 작업을 수행(CRUD)
- 자주 사용되는 모델 메서드
- all() , filter() , exclude() , values() , values_list()
- get() , create() , count() , exists() , update() , delete() , first() , last()
- 이러한 메서드들은 Model이 데이터베이스에 ORM를 할 수 있도록 도와준다.
ORM(Object-Relation Mapping)란?
- 객체와 관계형 데이터베이스를 연결(매핑)해 주는 것을 의미한다. 즉, SQL 쿼리를 사용하지 않고도 데이터베이스의 테이블과 객체를 연결하여 CRUD를 가능하도록 만들어 준다.
1. INSERT (생성)
데이타를 삽입하기 위해서는 먼저 테이블에 해당하는 모델(Model Class)로부터 객체를 생성하고, 그 객체의 save() 메서드를 호출하면 된다. 아래 예제는 Feedback() 생성자 안에 필요한 필드 값들을 채운 후 save() 메서드를 호출하는 코드이다. save() 메서드가 호출되면, SQL의 INSERT이 생성되고 실행되어 테이블에 데이타가 추가된다.
1
2
3
4
5
6
7
8
|
from feedback.models import *
from datetime import datetime
# Feedback 객체 생성
fb = Feedback(name = 'Kim', email = 'kim@test.com', comment='Hi', createDate=datetime.now())
# 새 객체 INSERT
fb.save()
|
.save() 매서드를 통해 생성 명령을 수행한다.
.create() 를 사용하는 경우와 결과
Post.objects.create(author=admin, title='This is a test title from django shell', content='This is a test title from django shell. This is a test title from django shell.')
>>> Post.objects.create(author=admin, title='This is a test title from django shell', content='This is a test title from django shell. This is a test title from django shell.')
<Post: This is a test title from django shell>
2. SELECT
Django는 디폴트로 모든 Django 모델 클래스에 대해 "objects" 라는 Manager (django.db.models.Manager) 객체를 자동으로 추가한다 (이 objects라는 이름을 변경할 수도 있지만, 대부분 그대로 사용한다).
데이타를 읽어오기 위해서는 Django 모델의 Manager 즉 "모델클래스.objects" 를 사용한다. 예를 들어, Feedback 이라는 모델의 경우 "Feedback.objects" 를 사용한다 (객체명이 아니라 클래스명을 사용함에 주의).
<자주 사용되는 주요 메서드>
- all() : 테이블 데이타를 전부 가져오기 위해서는 Feedback.objects.all() 과 같이 all() 메서드를 사용한다. 다음은 Feedback 테이블의 모든 데이타의 id와 name 컬럼을 출력하는 예이다.
12for f in Feedback.objects.all():s += str(f.id) + ' : ' + f.name + '\n' - get() : 하나의 Row만을 가져오기 위해서는 get() 메서드를 사용한다. 예를 들어, 아래는 Primary Key (일반적으로 id 컬럼)가 1인 row를 가져온다.
12row = Feedback.objects.get(pk=1)print(row.name) - filter() : 특정 조건에 맞는 Row들을 가져오기 위해서는 filter() 메서드를 사용한다. 예를 들어, 아래는 name 필드가 Kim 인 데이타만 가져온다.
1rows = Feedback.objects.filter(name='Kim') - exclude() : 특정 조건을 제외한 나머지 Row들을 가져오기 위해서는 exclude() 메서드를 사용한다. 예를 들어, 아래는 name 필드가 Kim이 아닌 데이타만 가져온다.
1rows = Feedback.objects.exclude(name='Kim') - count() : 데이타의 갯수(row 수)를 세기 위해 count() 메서드를 사용한다.
1n = Feedback.objects.count() - order_by() : 데이타를 키에 따라 정렬하기 위해 order_by() 메서드를 사용한다. order_by() 안에는 정렬 키를 나열할 수 있는데, 앞에 -가 붙으면 내림차순이다. 아래는 id를 기준으로 올림차순, createDate로 내림차순으로 정렬하게 된다.
1rows = Feedback.objects.order_by('id', '-createData') - distinct() : 중복된 값은 하나로만 표시하기 위해 distinct() 메서드를 사용한다. SQL의 SELECT DISTINCT 와 같은 효과를 낸다. 아래는 name필드가 중복되는 경우 한번만 표시하게 된다.
1rows = Feedback.objects.distinct('name') - first() : 데이타들 중 처음에 있는 row만을 리턴한다. 아래는 name필드로 정렬했을 때 처음 row를 리턴한다.
1rows = Feedback.objects.order_by('name').first() - last() : 데이타들 중 마지막에 있는 row만을 리턴한다. 아래는 name필드로 정렬했을 때 마지막 row를 리턴한다.
1rows = Feedback.objects.order_by('name').last()
위의 쿼리 메서드들은 하나 하나가 실제 데이타 결과를 직접 리턴한다기 보다는 쿼리 표현식(Django에서 QuerySet이라 한다)을 리턴하는데, 여러 메서드들을 체인처럼 연결하여 사용할 수 있다. 즉, 여러 체인으로 연결되어 리턴된 쿼리가 해석되어 DB에 실제 하나의 쿼리를 보내게 된다. 아래는 여러 메서드들을 사용하여 체인으로 연결한 예제이다. (매서드를 이어붙여 사용가능)
1
|
row = Feedback.objects.filter(name='Kim').order_by('-id').first()
|
3. UPDATE
데이타를 수정하기 위해서는 먼저 수정할 Row 객체를 얻은 후 변경할 필드들을 수정한다. 이어 마지막에 save() 메서드를 호출되면, SQL의 UPDATE이 실행되어 테이블에 데이타가 갱신된다. 아래는 id가 1인 Feedback 객체에 이름을 변경하는 코드이다. (.update() 매서드와 혼동주의)
1
2
3
|
fb = Feedback.objects.get(pk=1)
fb.name = 'Park'
fb.save()
|
4. DELETE
데이타를 삭제하기 위해서는 먼저 삭제할 Row 객체를 얻은 후 delete() 메서드를 호출하면 된다. 아래는 id가 2인 Feedback 객체를 삭제하는 코드이다.
1
2
|
fb = Feedback.objects.get(pk=2)
fb.delete()
|
'나는 이렇게 학습한다 > Framework' 카테고리의 다른 글
Django 에서 middleware 추가하기 (0) | 2023.09.26 |
---|---|
FastAPI _ BaseSettings 을 lru_cache 할 때, unhashable type 에러 해결방법 (0) | 2022.10.26 |
FastAPI _ Custom Exception 만드는 방법 (0) | 2022.05.04 |
DRF 궁금한 것 모음 (0) | 2022.02.03 |
'ManyToManyField' 또는 '중간테이블'로 데이터 가져오는 방법 (0) | 2021.11.19 |