[점프 투 장고 01](2-02 모델)

givemacdonalds·2023년 12월 23일
0

TIL

목록 보기
14/16
post-thumbnail

이전 프로젝트에서 백엔드를 담당하게 되었다. 나에게 친숙한 언어는 python 이었기 때문에 고민할 필요도 없이 django를 선택했다. document의 예제와 구글링을 하면서 django에 대해서 공부했다. 2개월 이라는 기한이 있었기에 물 흐르듯 개념을 가볍게 훑어보고 gpt와 구글링에 의존하면서 프로젝트를 진행했고 굉장히 아쉬운 결과물이 나왔다.
이전에 공부하면서 기록을 하지 못한 것이 아쉬워서 기록하고자 한다.

django

The web framework for perfectionists with deadlines
마감에 쫓기는 완벽주의자를 위한 웹 프레임워크

장고를 사용하면 웹프로그램을 마감에 쫓기지 않을 정도로 빠르게 만들 수 있으면서도 완성도가 완벽에 가깝다 라는 의미란다. 나는 왜...?

웹 프레임워크

웹 프로그램을 만들기 위한 스타터 키트라고 생각하면 된다.


장고 개발 환경 준비하기

m1 macOS
python == 3.11.4
django == 4.2.4

장고 프로젝트

project

장고에는 프로젝트라는 개념이 존재한다. 장고의 프로젝트는 하나의 웹 사이트라고 생각하면 된다. 장고 프로젝트를 생성하면 웹사이트를 생성하는 것과 같다.

application

프로젝트 안에는 여러 개의 app이 존재한다. app은 관리자 앱, 인증 앱 등과 같이 장고가 기본으로 제공하는 앱과 개발자가 직접 만든 앱을 칭한다.

장고에서 말하는 앱은 안드로이드/iOS 앱과 성격이 다르며, 장고의 앱은 프로젝트를 구성하는 작은 단위의 기능이다.

루트 디렉터리 생성

장고 프로젝트는 여러 개가 될 수 있으므로 프로젝트를 모아 둘 루트 디렉터리를 생성 해야 한다.

% mkdir projects
% cd projects

root 디렉터리 : projects

가상환경 진입

% conda activate Aigraphers

Aigraphers라는 가상환경에 진입하게 되면 다음과 같이 터미널이 변하게 된다.

(Aigraphers) % 

하지만 편의를 위해서 (Aigraphers) % %로 나타낼 것이다. 감안하고 봐주ㅓ

장고 프로젝트 생성

% django-admin startproject config .

config : config라는 장고 프로젝트를 생성
. : 현재 디렉토리라는 의미이며, 원하는 디렉터리 경로를 적어도 된다.

개발 서버 구동하고 웹 사이트에 접속

% python manage.py runserver

아래와 같은 문구가 나오게 되면 서버가 구동이 된 것이다.

Starting development server at http://127.0.0.1:8000/
Quit the server with CONTROL-C.

http://127.0.0.1:8000/ 를 접속해보면 다음과 같은 웹사이트가 보이게 된다.

정말 쉽죠?

장고 서버가 http://127.0.0.1:8000/ 로 시작되었고 CONTROL-C를 입력하게 되면 서버가 중지 된다.

개발을 위해 실행되는 장고 서버는 로컬호스트로 실행되기 때문에 로컬 서버라고 부른다.

또한 http://localhost:8000/라고 입력해도 동일한 결과를 얻을 수 있다. localhost127.0.0.1은 모두 현재 사용중인 내 PC를 가리키는 아이피 주소이기 때문이다.


장고 기본 요소

URL과 View

App

앞에서 생성한 프로젝트는 단독으로 아무런 일도 할 수 없다. 프로젝트에 기능을 추가하기 위해서는 앱을 생성 해야 한다. 게시판 기능을 담당할 pybo 앱을 생성 할 것이다.

% django-admin startapp pybo

디렉토리 창을 확인해보면 pybo라는 디렉토리가 생성 되어 있다.

Hello Pybo

로컬서버를 구동하고 http:127.0.0.1:8000/pybo 페이지를 요청하면 다음과 같이 Page not found(404)라는 오류가 발생한다.404는 HTTP 오류코드이다.

오류의 내용을 읽어보면 config/urls.py 파일에 요청한 pybo/ URL에 해당되는 매핑이 없다고 한다.
장고의 urls.py 파일은 페이지 요청이 발생하면 가장 먼저 호출되는 파일로 URL과 view 함수 간의 매핑을 정의한다.

urls.py

config/urls.py

from django.contrib import admin
from django.urls import path

from pybo import views

urlpatterns = [
    path('admin/', admin.site.urls),
    path('pybo/',views.index),
]

매핑을 추가하기 위해서 urls.py의 urlpatterns에 해당 url을 추가하였다.
http://localhost:8000/pybo가 실제 URL이지만 호스트명과 포트가 생략된 pybo/로 매핑 해야한다. 왜냐하면 호스트(localhost)와 포트(8000)는 서버가 어떤 환경에서 실행되는지에 따라 변하기 때문이다.

pybo/pybo라고 하지 않은 이유는 URL을 정규화하는 장고의 기능 때문이다. 그래서 특별한 경우가 아니면 /를 붙여줘야 한다.

views.py

매핑을 완료했고 페이지를 요청해보면 사이트에 연결 할 수 없다고 나온다. 왜냐하면 URL 매핑에 추가한 뷰 함수 views.index가 없기 때문이다.

pybo/views.py

from django.shortcuts import render
from django.http import HttpResponse

def index(request):
    return HttpResponse('안녕하세요 pybo입니다.')

뷰 함수를 작성한 후에 http://localhost:8000/pybo/페이지를 요청하면 다음과 같은 결과를 볼 수 있다.

URL 분리

pybo앱에 관련한 것들은 pybo 앱 디렉터리 하위에 위치해야 한다. 하지만 이대로라면 pybo와 관련된 URL 매핑을 추가 할 때마다 config/urls.py을 수적 해야한다.

urls.py

config/urls.py

from django.contrib import admin
from django.urls import path,include
//from pybo import views # 더 이상 필요하지 않음

from pybo import views

urlpatterns = [
    path('admin/', admin.site.urls),
    path('pybo/',include('pybo.urls')),
]

path('pybo/',include('pybo.urls))의 의미는 pybo/ 로 시작하는 페이지를 요청하면 이제 pybo/urls.py 파일의 매핑 정보를 읽어서 처리하라는 뜻이다.

이제 pybo 앱과 관련된 url은 pybo/urls.py 파일에서만 수정하면 된다.
pybo/urls.py 생성

from django.urls import path

from . import views

urlpatterns = [
    path('',views.index),
]

URL을 config와 pybo로 분리하였지만 똑같이 http://localhost:8000/pybo/로 요청하면 된다는 것을 알 수 있다.

모델

장고는 모델을 이용하여 DB를 처리한다. 장고의 모델은 SQL쿼리문 없이 데이터를 쉽게 처리할 수 있다.

migration

데이터가 필요한 앱만 마이그레이션이 필요하다. migration은 테이블 및 필드의 생성, 삭제, 변경 등과 같이 데이터베이스에 대한 변경사항을 알려주는 것이다. 실제로 프로젝트를 진행시에 makemigration, migrate만 순차적으로 사용했었다.

클래스 모델을 만들고 makemigrations 명령어를 입력해서 데이터베이스 쪽에서 테이블을 생성할 수 있도록 migrate 하는 것이 끝입니다.

나중에 자세하게 알아보도록 한다.

모델 작성하기

모델의 속성

Question 모델

[속성] 			[설명]
subject			질문의 제목
content			질문의 내용
create_date		질문을 작성한 일시

Answer 모델

[속성] 			[설명]
question		질문(어떤 질문의 답변인지 알아야함)
content			답변의 내용
create_date		답변을 작성한 일시

models.py

pybo/models.py

from django.db import models

class Question(models.Model):
    subject = models.CharField(max_length=200)
    content = models.TextField()
    create_date = models.DateField()

class Answer(models.Model):
    question = models.ForeignKey(Question,on_delete=models.CASCADE)
    content = models.TextField()
    create_date = models.DateTimeField()

Answer 모델은 질문에 대한 답변에 해당하므로 Question모델을 속성으로 가져야 한다.
question = models.ForeignKey(Question,on_delete=models.CASCADE)

on_delete=model.CASCADE는 답변과 연결된 질문이 삭제 될 경우 답변도 함께 삭제된다는 의미이다.

테이블 생성

config/settings.py

'''(생략)'''
INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'pybo.apps.PyboConfig',
]
'''(생략)'''

INSTALLED_APPS에 추가한 pybo.apps.PyboConfig 클래스는 pybo/apps.py 파일에 있는 클래스 이다.
pybo/apps.py

from django.apps import AppConfig


class PyboConfig(AppConfig):
    default_auto_field = 'django.db.models.BigAutoField'
    name = 'pybo'

앱을 생성 할 때 자동으로 생성되는 부분이여서 따로 파일을 만들 필요가 없다. 하지만 INSTALLED_APPS 항목에 추가하지 않으면 이어지는 작업을 진행 할 수 없다.(클래스명을 잘 확인하고 항목에 추가 할 것!)

makemigrations

모델이 신규로 생성되거나 변경되면 makemigrations명령을 먼저 수행해야한 후에 migrate명령을 수행 해야한다. 다음 명령어를 순서대로 작성 해야 한다.

% python manage.py makemigrations
Migrations for 'pybo':
  pybo/migrations/0001_initial.py
    - Create model Question
    - Create model Answer

위 명령어를 실행하면 pybo/migrations/0001_initial.py라는 파일이 자동으로 생성 된다.
makemigrations는 작업파일을 생성하는 것이기 때문에 makemigrations명령을 수행하더라도 실제로 테이블이 생성되지 않고 migrate 명령을 통해서만 실제 테이블 작업이 가능하다.

만약 모델을 잘못 migration 해도 migrations의 디렉터리의 파일을 삭제하고 다시 makemigrations하면 되기 때문에 겁먹지 않아도 된다.

sqlmigrate

makemigrations로 데이터베이스 작업 파일을 생성하고 migrate 명령을 하기 전에 어떤 쿼리문이 실행되는지 sqlmigrate로 확인해 볼 수 있다.

% python manage.py sqlmigrate pybo 0001

앱 이름과 생성된 파일의 일련 번호를 작성해주면 된다.

migrations

이제 실제 테이블을 생성한다.

% python manage.py migrate       
Operations to perform:
  Apply all migrations: admin, auth, contenttypes, pybo, sessions
Running migrations:
  Applying contenttypes.0001_initial... OK
  Applying auth.0001_initial... OK
  Applying admin.0001_initial... OK
  ...(생략)...

0개의 댓글