20230424 TIL - django 프레임워크 (1)

ohyujeong·2023년 4월 24일
0

TIL

목록 보기
11/27
post-thumbnail

📖 오늘의 학습

  • django 프레임워크를 사용한 웹 개발
    django를 사용하기 위한 개발환경을 세팅하고 앱 생성, url 세팅, Model생성을 알아본다.

개발환경 세팅

1. Python 가상환경 설정하기

python의 venv 모듈을 사용하여 django 프로젝트를 만들 가상환경을 만들어준다.
👉 python프로젝트들을 각각의 환경에 맞게 관리하기 위하여 프로젝트마다 하나의 가상환경을 생성하여 관리한다.

가상환경 생성

아래 명령어로 django-venv 의 이름으로 가상환경 프로젝트가 만들어지고 해당 이름으로 폴더가 없다면 새로 프로젝트 폴더를 생성한다.

python -m venv django-venv

아래와 같이 새로운 프로젝트 폴더 django-venv가 생성된 것을 확인할 수 있다.

💡 만약 conda 가상환경에 있는 경우 터미널 명령어 앞에 (base) 라고 표기된다. conda deactivate 로 가상환경에서 빠져 나온 후 venv 가상환경을 세팅한다.

가상환경 활성화

# 활성화
source django-venv/bin/activate

# 비활성화
deactivate

터미널 명령어 앞에 가상환경의 이름 (django-venv) 이 표시된다면 가상환경이 활성화되었다는 것이다.

2. Django 설치하기

가상환경이 활성화된 상태에서 아래 명령어를 이용하여 django를 설치한다. 가상환경폴더 안에 있는 pip 를 사용하여 install 해준다

django-venv/bin/pip install django

# django 버전체크
django-venv/bin/python -m django --version

이렇게 django 프레임워크를 venv 가상환경에 설치하는 것이 완료되었다!

Django Project 생성하기

1. 새로운 django 프로젝트 생성하기

가상환경을 만들고, 이어서 mysite 라는 이름의 django 프로젝트를 생성한다.

django-admin startproject mysite

생성한 프로젝트의 서버를 아래 명령어로 실행하고 http://127.0.0.1:8000 로 서버가 잘 돌아가는지 확인한다.

python manage.py runserver

2. django 앱 생성하기

polls 라는 이름의 앱을 프로젝트에 생성한다.

python manage.py startapp polls

이렇게 앱 생성이 완료되었다면 이제 해당 앱이 작동할 수 있도록 몇가지 파일을 수정해주어야한다.

mysite/urls.py

http://127.0.0.1:8000/polls url로 접근할 수 있도록 설정한다. include 는 이것의 인자로 들어가있는 polls 폴더의 url 파일의 url설정에 따르겠다는 의미이다.

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

urlpatterns = [
    path("admin/", admin.site.urls),
    path("polls/", include('polls.urls')) # 추가
]

polls/urls.py

mysite/urls.py 의 설정에 의해 이 파일의 urlpattern을 따르게 된다. polls 폴더의 view 파일에 있는 함수 index 를 실행한다는 의미이다.

from django.urls import path
from . import views

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

polls/views.py

HttpResponse 를 import하여 응답을 리턴할 수 있도록 한다. 아래는 화면에 간단하게 "Hello, world."를 출력한다.

from django.http import HttpResponse

def index(request):
    return HttpResponse("Hello, world.")

여기서 http://127.0.0.1:8000/polls 뒤에 다른 경로를 추가하게 된다면 아래와 같이 polls/urls.py, polls/views.py 파일을 변경하면 된다.

# polls/urls.py
from django.urls import path
from . import views

urlpatterns = [
    path('',views.index, name='index'),
    path('some_url/',views.some_url) # http://127.0.0.1:8000/polls/some_url 경로 추가
]
# polls/views.py
from django.http import HttpResponse

def index(request):
    return HttpResponse("Hello, world.")

def some_url(request):
    return HttpResponse("Some url을 구현해 봤습니다.")

3. 모델 (Model) 생성하기

django의 model은 DB에 저장되어 있는 데이터를 테이블의 형태로 읽어서 이를 코드로 접근할 수 있도록 하는 ORM(Object Relational Mapping(객체-관계-매핑))의 기능을 한다.

모델을 생성하는 과정은 다음과 같다.
1. 모델을 models.py에 추가한다.
2. 모델을 DB의 테이블 형태로 만들어주기 위한 '마이그레이션'이라는 작업을 수행한다.
3. 추가한 모델에 맞는 테이블을 만든다.

polls/models.py

class 인 Question과 Choice는 DB의 테이블이고, 각 클래스 내에 정의된 변수들은 DB 테이블의 컬럼에 해당한다.
CharField, DateTimeField 와 같이 field를 지정할 수 있는데 이것은 DB의 데이터 형에 해당한다.
Field option 더보기

from django.db import models

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)

mysite/settings.py

마이그레이션을 위해 프로젝트 설정파일에 polls 앱을 추가한다.

...
# Application definition

INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'polls.apps.PollsConfig', # polls 앱을 추가해준다
]
...

마이그레이션 파일 생성

python manage.py makemigrations polls

마이그레이션으로 실행될 SQL문장 살펴보기

python manage.py sqlmigrate polls 0001

마이그레이션 실행

python manage.py migrate

마이그레이션 롤백

#마이그레이션을 0001버전으로 다시 롤백하기
python manage.py migrate polls 0001

3. 관리자(Django Admin) 계정 생성 & 모델 등록

django는 기본적으로 사용자가 만든 model을 기반으로 이것을 CRUD(Create, Read, Update, Delete)할 수 있는 관리자 페이지를 제공한다.

이 페이지에 로그인할 수 있는 계정을 생성하고 model을 등록하여 관리자 페이지에서 model에 접근하고 수정할 수 있도록 한다.

관리자(Django Admin) 계정 생성

아래 명령어로 관리자 계정을 생성하고 http://127.0.0.1:8000/admin 로 관리자 페이지에 로그인한다.

python manage.py createsuperuser

polls/admin.py

관리하고자 하는 모델을 import하고 등록한다.

from django.contrib import admin
from .models import *

admin.site.register(Question)
admin.site.register(Choice)

polls/models.py

__str__ 함수를 정의해줌으로써 관리자 페이지에서 나타나는 Question테이블의 레코드를 편하게 식별할 수 있도록 도와준다.

from django.db import models

class Question(models.Model):
    question_text = models.CharField(max_length=200)
    pub_date = models.DateTimeField('date published')
    
    # 관리자 페이지의 제목으로 나타나는 string
    def __str__(self):
        return f'제목: {self.question_text}, 날짜: {self.pub_date}'

3. Django Shell 활용하기

Django Shell을 통해 만들었던 모델을 수정, 삭제하고 DB에까지 적용시킬 수 있다.

Django Shell 실행하기

python manage.py shell

Django Shell을 활용하여 모델에 접근하기

  • 모델 조회
#models.py 파일에 정의된 모든 모델 가져오기
>>> from polls.models import *
>>> Question

#모든 Question,Choice 오브젝트 가져오기
>>> Question.objects.all()
>>> Choice.objects.all()

#첫번째 Choice 오브젝트 가져오기
>>> choice = Choice.objects.all()[0]
>>> choice.id
>>> choice.choice_text
>>> choice.votes

#첫번째 Choice와 연결된 Question 가져오기
>>> choice.question
>>> choice.question.pub_date
>>> choice.question.id

#해당 Question과 연결되어 있는 모든 Choice 가져오기 
>>> question.choice_set.all()
  • 모델 수정
#"커피 vs 녹차" 라는 내용의 새로운 Question 오브젝트를 생성하고 'q1'이라는 변수에 저장하기
>>> q1 = Question(question_text = "커피 vs 녹차")

#tiemzone을 활용하여 새로운 오브젝트 'q1'의 생성시각을 설정하기
>>> from django.utils import timezone
>>> q1.pub_date = timezone.now()
  • 수정한 모델을 DB에 반영
#새로운 Question 오브젝트 'q1'을 데이터베이스에 저장하기
>>> q1.save()
>>> q3 = Question(question_text = "abc")
>>> q3.pub_date = timezone.now()
>>> q3.save()
  • 모델 오브젝트 생성 및 활용
#create() 메서드를 활용하여 q3와 연결된 새로운 Choice 오브젝트를 생성하고, choice_text 필드에 값을 넣어주기
>>> q3.choice_set.create(choice_text = "b")

#새로운 Choice 오브젝트를 생성하고 question 필드에 q3 값을 넣어 연결하기
>>> choice_c = Choice(choice_text='c', question=q3)

#새로운 Choice 오브젝트를 데이터베이스에 저장하기
>>> choice_c.save()

#Question 오브젝트 중 가장 마지막으로 만들어진 것을 가져오기
>>> q = Question.objects.last()

#해당 오브젝트의 question_text에 새로운 내용을 더해 수정하기
>>> q.question_text = q.question_text + '???'

#Choice 오브젝트 중 가장 마지막으로 만들어진 것을 가져오기
>>> choice = Question.objects.last()

#해당 오브젝트에 연결된 Question을 통해서 choice set을 가져오기
>>> choice.queston.choice_set.all()
  • 모델 오브젝트 삭제
#해당 오브젝트를 삭제하기
>>> choice.delete()
  • 모델 필터링
#get() 메서드를 사용하여 조건에 해당하는 오브젝트를 필터링하기
>>> Question.objects.get(id=1)
>>> q = Question.objects.get(question_text__startswith='휴가를')
>>> Question.objects.get(pub_date__year=2023) #get으로 여러가지 오브젝트를 가져오려고 한다면 에러발생
polls.models.Question.MultipleObjectsReturned: get() returned more than one Question

#filter() 메서드를 사용하여 조건에 해당하는 오브젝트를 필터링하기
>>> Question.objects.filter(pub_date__year=2023)
<QuerySet [<Question: 제목: 휴가를 어디서 보내고 싶으세요?, 날짜: 2023-02-05 18:52:59+00:00>, <Question: 제목: 가장 좋아하는 디저트는?, 날짜: 2023-02-05 18:53:27+00:00>, ...]>
>>> Question.objects.filter(pub_date__year=2023).count()

#쿼리셋의 SQL 쿼리 살펴보기
>>> Question.objects.filter(pub_date__year=2023).query
>>> print(Question.objects.filter(pub_date__year=2023).query)
SELECT "polls_question"."id", "polls_question"."question_text", "polls_question"."pub_date" FROM "polls_question" WHERE "polls_question"."pub_date" BETWEEN 2023-01-01 00:00:00 AND 2023-12-31 23:59:59.999999

>>> Question.objects.filter(question_text__startswith='휴가를').query
>>> print(Question.objects.filter(question_text__startswith='휴가를').query)
SELECT "polls_question"."id", "polls_question"."question_text", "polls_question"."pub_date" FROM "polls_question" WHERE "polls_question"."question_text" LIKE 휴가를% ESCAPE '\'

>>> q = Question.objects.get(pk=1)
>>> q.choice_set.all()
>>> print(q.choice_set.all().query)
SELECT "polls_choice"."id", "polls_choice"."question_id", "polls_choice"."choice_text", "polls_choice"."votes" FROM "polls_choice" WHERE "polls_choice"."question_id" = 1

#startswith 연산자를 활용하여 오브젝트를 필터링하기
>>> q = Question.objects.filter(question_text__startswith='휴가를')
>>> q2 = Question.objects.filter(pub_date__year=2023)

#contains 연산자를 활용하여 오브젝트를 필터링하기
>>> Question.objects.filter(question_text__contains='휴가')

>>> Choice.objects.all()
>>> Choice.objects.filter(votes__gt=0)

#해당 쿼리셋에 대한 SQL 쿼리를 생성하기
>>> Choice.objects.filter(votes__gt=0).query
>>> print(Choice.objects.filter(votes__gt=0).query)
SELECT "polls_choice"."id", "polls_choice"."question_id", "polls_choice"."choice_text", "polls_choice"."votes" FROM "polls_choice" WHERE "polls_choice"."votes" > 0

>>> choice=Choice.objects.first()
>>> choice.votes=5
>>> choice.save()

#정규표현식을 활용하여 조건에 해당하는 오브젝트들을 필터링하기
>>> Question.objects.filter(question_text__regex=r'^휴가.*어디')
>>> print(Question.objects.filter(question_text__regex=r'^휴가.*어디').query)
SELECT "polls_question"."id", "polls_question"."question_text", "polls_question"."pub_date", "polls_question"."owner_id" FROM "polls_question" WHERE "polls_question"."question_text" REGEXP ^휴가.*어디

#Question의 question_text 필드 값이 '휴가'로 시작하는 모든 Choice 오브젝트를 필터링하기
>>> Choice.objects.filter(question__question_text__startswith='휴가')

#exclude() 메서드를 사용하여 question_text 필드 값이 '휴가'로 시작하는 모든 Choice 오브젝트를 제외하고 필터링하기
>>> Question.objects.exclude(question_text__startswith='휴가')

정규식 더 알아보기 : https://ko.wikipedia.org/wiki/%EC%A0%95%EA%B7%9C_%ED%91%9C%ED%98%84%EC%8B%9D


📝 주요메모사항

datetime 을 활용하여 현재 날짜와 시간 구하기

from datetime import datetime
now = datetime.now()

timezone 을 활용하여 현재 날짜와 시간구하기

from django.utils import timezone
now = timezone.now()

timedelta 를 활용하여 시간의 차이를 구하기

from datetime import datetime, timedelta
now = datetime.now()
week_after = now + timedelta(days=7)
f"반납 예정일은 {week_after} 입니다."

😵 공부하면서 어려웠던 내용

Django Shell을 활용하는 부분에서 굉장히 여러가지 방법으로 모델에 접근하는 방법이 있어 조금 헷갈렸고, 정규식에 대해서 잘 몰랐는데 이번 기회에 정규식을 배워놔야겠다고 생각했다.

profile
거친 돌이 다듬어져 조각이 되듯

0개의 댓글