[4/8] TIL - Django를 이용한 API 만들기 [1]

Sangwon Jwa·2024년 4월 8일

데브코스 TIL

목록 보기
11/54
post-thumbnail

📖 학습 주제


  1. Python 가상 환경 설정
  2. Django 앱 생성하기
  3. 모델 (Model)
  4. Django Shell

✏️ 주요 메모 사항 소개


Python 가상 환경 설정하기

로컬 서버에 프로젝트를 만들고 작업하지 않고 프로젝트마다 가상환경을 설정해주어야 하는 이유

  • 서로 다른 유형과 목적의 프로젝트들을 한 공간에 넣어서 관리할 시, 매번 하나의 프로젝트를 실행할 때 마다 그에 맞춰서 환경을 체크하고 변경해주어야 하며 심한 경우에는 프로젝트 간의 충돌이 발생할 수도 있기 때문이다.
  • 따라서 이와 같은 문제점들을 방지하고, Python 프로젝트들을 각각의 목적에 맞게 효율적으로 관리할 수 있다는 측면에서 Python 프로젝트를 다룰 때에는 가상환경을 만들어 사용하는 방법이 권장되고 있다.
  1. Python 가상 환경 생성
    py -m venv venv-name

  2. 활성화
    Windows : project-name\Scripts\activate.bat
    Mac/Linux : source project-name/bin/activate

  3. 비활성화
    deactivate

  4. Python 가상 환경이 활성화된 상태에세 Django를 설치
    python -m pip install Django

  5. Django 설치 확인
    Windows : django-admin -version
    Mac/Linux : python -m django --version

  6. Django 프로젝트 생성
    django-admin startproject project-name

  7. 서버 실행
    python manage.py runserver

Django App 생성하기

프로젝트는 하나의 웹 사이트를 의미하고 내부의 기능들은 App 이라고 한다. 하나의 프로젝트는 여러개의 App 들로 이루어진다.

  • App 생성

python manage.py startapp app-name

  • URL 설정
  1. 프로젝트 디렉토리의 urls.py 의 urlpatterns 에 생성한 App 관련 path를 추가
urlpatterns = [
    # polls 라는 새로운 App을 생성 후 URL 요청시 polls/ 와 관련된 URL 이라면 polls 디렉토리 안의 urls.py 참조
    path('polls/', include('polls.urls')),
    path('admin/', admin.site.urls),
]
  1. polls 앱 디렉토리의 urls.py에 url 추가
from django.urls import path

# url이 공백일 시 views.py 에서 index를 뷰로 호출
urlpatterns = [
    path('', views.index, name='index'),
]
  1. view 만들기
from django.shortcuts import render
from django.http import HttpResponse

# index라는 이름의 뷰 생성
def index(request):
    return HttpResponse("Hello world.")

Django Tutorial Part 1 : 모델 (Models)

DB에 저장된 데이터를 불러오는 역할을 하는 부분, 모델 생성 -> 마이그레이션 생성 -> 테이블 생성 의 과정을 거침.
마이그레이션 이란 Django 모델의 변경 사항을 DB에 반영하는 것을 말한다. 모델과 테이블은 1:1 매칭된다.

모델 만들기

  1. polls 앱 안의 models.py모델 만들기 ( 휴가를 간다면 어디로 갈건지의 설문을 가진 테이블)
class Question(models.Model):
    question_text = models.CharField(max_length=200)
    pub_date = models.DateTimeField('date published')

class Choice(models.Model):
    question = models.ForeignKey(Question, on_delete=models.CASCADE)
    choice_text = models.CharField(max_length=200)
    votes = models.IntegerField(default=0)
  1. 프로젝트(mysite) 폴더의 settings.py 등록
INSTALLED_APPS = [
	# settings.py 에 INSTALLED_APPS 내의 polls 앱의 config 파일을 등록
    'polls.apps.Pollsconfig',
    
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
]
  1. 마이그레이션 만들기
    python manage.py makemigrations polls
  1. 마이그레이션 확인
    python manage.py sqlmigrate polls 0001
  1. 테이블 생성
    python manage.py migrate

 

  • 필드 변경 (모델 구조 변경)
  1. 필드 변경
# is_something , average_score 변수 추가함
class Question(models.Model):
    question_text = models.CharField(max_length=200)
    pub_date = models.DateTimeField('date published')
    is_something = models.BooleanField(default=False)
    average_score = models.FloatField(default=0.0)
  1. 마이그레이션 실행
    python manage.py makemigrations
    위의 명령어 실행시 기존에 있던 polls.0001 이후에 polls.0002 마이그레이션이 생성됨.
  1. 확인
    sqlite3 db.sqlite3 실행 후,
    .tables 실행 시 테이블 목록을 볼 수있다.
    .shcema polls_question 으로 테이블을 살펴보면 추가된 필드를 포함한 SQL 문을 찾아 볼 수 있다.
  • 만약 다시 polls.0001 로 바꾸고 싶다면 python manage.py migrate polls 0001 명령어를 실행하면 된다. 그 후 0002 파일을 삭제한다.

관리자 계정 생성하고 접속하기

python manage.py createsuperuser 이후 /admin 접속 시 usernamepassword로 접속 가능.

  • 만든 모델을 Admin 사이트에서 사용하기 위해서는 모델을 admin에 등록하는 과정이 필요하다. polls 디렉토리 안에 admin.py 파일에 다음 코드를 추가한다.
from django.contrib import admin
from .models import *
# Register your models here.

# polls 모델 admin 등록
admin.site.register(Question)
admin.site.register(Choice)

  • Question 모델에 __str__(self) 메소드 추가할 시 이름 변경 가능
def __str__(self):
        return f'제목: {self.question_text}, 날짜: {self.pub_date}'

Django Shell 사용하기

python manage.py shell 명령어 실행 시 django shell 이용 가능 -> 만들었던 모델들을 활용 가능.

현재 시간 구하기

파이선 에서는 datetime 라이브러리를 통해 현재 시간을 알 수 있다. datetime.now() 를 사용해면 현재 시간을 알 수 있지만 django는 여러 국가에서 사용할 웹 사이트를 만드는 프레임워크 이므로 추가적으로 timezone을 알아야 한다. 이는 django.utilstimezone 을 이용하여 알 수 있다.

from django.utils import timezone
timezone.now()

레코드 생성하기

  • Django Shell 에서 레코드를 생성하려면 save() 메소드를 사용하면 된다. 다만 안의 필드 값들이 NULL 이면 안되기 때문에 각각 양식에 맞게 입력해 주어야 한다. 아래의 예시에서는 pub_date 가 필요하기 때문에 timezone을 이용하여 현재 시간을 넣어주었다.
from polls.models import *
from django.utils import timezone
q1 = Question(question_text = "커피 vs 녹차")
q1.pub_date = timezone.now()
q1.save()
  • Question 모델 안에 pub_date 인자에 auto_nowauto_now_add 값을 True 로 설정한다면 자동으로 시간을 추가할 수 있다.
# auto_now : 모델이 업데이트 될 때 마다 시간 갱신
# auto_now_add : 모델이 처음 생길 때의 시간을 추가
pub_date = models.DateTimeField(auto_now_add=True)
  • Question에 따른 Choice를 만드는 방법은 여러가지가 있다.
# question 의 choice_set을 이용해 create()
q1 = Question.objects.all().first()
q1.choice_set.create(choice_text = '산')
# choice의 인자로 question을 넣어서 save()
new_choice = Choice(choice_text = '산', question=q1)
new_choice.save()

레코드 수정, 삭제하기

# 수정
q = Question.objects.first()
q.question_text = q.question_text + '???'
# 삭제 1
choice = choice.objects.last()
choice.delete()
# 삭제 2
q.choice_set.delete()

모델 필터링

from polls.models import *
# 조건에 맞는 하나의 값을 가져오기, 조건에 맞는 것이 여러개면 에러 발생
Question.objects.get(id=1)
Question.objects.get(question_text__startswith='휴가를')
Question.objects.get(pub_date__second=59)
# 조건에 맞는 여러개의 값을 가져오기
Question.objects.filter(pub_date__year=2023)
Question.objects.filter(question_text__contains='휴가')
# 조건에 맞는 값 가져오기 (gt : greater than)
Choice.objects.filter(votes__gt=0)
# 조건에 맞는 값 삭제하기 (votes 가 0인 choice 삭제)
Choice.objects.filter(votes=0).delete()
# 정규 표현식을 이용해서 조건 활용하기
Question.objects.filter(question_text__regex=r'^휴가.*어디')

모델 관계기반 필터링

from polls.models import *
# 휴가로 시작하는 것 추출
Choice.objects.filter(question__question_text__startswith='휴가')
# 휴가로 시작하지 않는 것 추출
Question.objects.exclude(question_text__startswith='휴가')

모델 메소드

  • Question 모델에 메소드 추가 (was_published_recently)
class Question(models.Model):
    question_text = models.CharField(max_length=200)
    pub_date = models.DateTimeField(auto_now_add=True)

    def __str__(self):
        if self.was_published_recently():
            new_badge = "NEW!!!"
        else:
            new_badge = ''
        return f'{new_badge} 제목: {self.question_text}, 날짜: {self.pub_date}'
    
    # pub_date 가 어제보다 크면(현재와 더 가까우면) True
    def was_published_recently(self):
        return self.pub_date >= timezone.now() - datetime.timedelta(days=1)
  • django shell 에서 확인

💦 공부하며 어려웠던 내용


  • reportmissingmodulesource 오류 해결
    VScode 내에서 가상환경의 인터프리터가 아닌 시스템 상의 인터프리터를 사용하고 있기 때문에 발생. 인터프리터 언어 설정을 앞서 생성했던 django-venv 가상환경 내의 python.exe 파일로 변경 시 노란 밑줄이 생기는 오류를 해결할 수 있다.

  • 또한 VScode 내의 터미널인 Git Bash 로 실습을 진행 중 sqlite3 : Command Not Found 오류가 발생해서 찾아보니 python 환경 변수가 잘못 설정 되어 있었다. 제대로된 경로로 수정하니 오류를 해결할 수 있었다.

0개의 댓글