본문 바로가기

dev course - DE/TIL

[데브코스] TIL 11일차

Django에서의 Projects vs. Apps

[출처] https://studygyaan.com/django/best-practice-to-structure-django-project-directories-and-files?source=post_page-----14d230358d72--------------------------------
[출처] https://rai-shahnawaz.medium.com/creating-a-django-project-the-right-way-14d230358d72

  • projects ⊃ apps
  • project : 하나의 특정 웹사이트를 위한 설정들과 앱들의 모임. 여러개의 앱을 가질 수 있으며, 하나의 앱은 여러 프로젝트 안에 존재할 수도 있음
  • app : 웹 어플리케이션으로, 어떤 동작을 수행함

 

Django app 생성하기

polls app 생성

python manage.py startapp polls

 

구조

 

polls/views.py

from django.http import HttpResponse

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

 

 

mysite/urls.py

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

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

 

 

polls/urls.py

from django.urls import path
from . import views

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

 

URL 경로(path) 설정하기

polls/views.py

from django.http import HttpResponse

def index(request):
    return HttpResponse("Hello, world.")
    
def some_url(request):
    return HttpResponse("some url을 구현해 봤습니다.")

 

 

polls/urls.py

from django.urls import path
from . import views

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

 

 

 

관계형 데이터베이스(RDB)

데이터를 행과 열로 이루어진 테이블 형태고 구성하고, 테이블 간의 관계를 정의하는 데이터베이스

 

  • 열(column)
    - 테이블에 존재하는 필드(field)를 나타냄. 앞으로 테이브르이 행에 저장된 내용들이 무엇인지 표시함

  • 행(row)
    - 테이블에 저장된 데이터 레코드(record)
Django에서는 모델(model)이라는 개념을 활용해 관계형 데이터베이스와의 연동을 구현함
모델 - 테이블에 해당하며, 각 모델은 필드를 가지고 있음

 

 

 

모델(models) 만들기

서버는 들어온 요청에 대해서 정해진 답을 주는게 아닌, DB에서 값을 불러와 보여주는게 일반적

모델은 DB를 테이블 별로 읽어서 하나의 테이블에 저장된 값을 코드에서 읽을 수 있게 해줌 → ORM(Object-Relational Mapping)


1. 모델 생성

polls/models.py에 다음 추가

from django.db import models

class Question(models.Model): # 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)

 

2. 마이그레이션을 만들기 위해, 우리가 만들고 있는 앱을 settings.py에 등록

현재 만들고 있는 polls 기준으로 설명하면 settings.py > INSTALLED_APPS 리스트에 polls > apps.py > PollsConfig를 'polls.apps.PollsConfig'로 추가

 

3. 모델을 DB에 적용하기 위한 마이그레이션 파일 생성

# polls라는 이름으로 모델의 변경사항을 담은 마이그레이션 파일 생성
python3 manage.py makemigrations polls

# 0001_initial.py 내용 확인
python3 manage.py sqlmigrate polls 0001

 

4. 마이그레이션을 실행해 변경된 내용 DB에 적용
python3 manage.py migrate

 

 

 

Django의 다양한 모델 필드 활용하기

참고 : https://docs.djangoproject.com/en/5.0/ref/models/fields/

 

Model field reference | Django documentation

The web framework for perfectionists with deadlines.

docs.djangoproject.com

 

1. 모델의 필드를 추가/변경할때

  • polls/models.py 변경 후,
from django.db import models

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)

class Choice(models.Model):
    question = models.ForeignKey(Question, on_delete=models.CASCADE)
    choice_text = models.CharField(max_length=200)
    votes = models.IntegerField(default=0)

 

  • 터미널에서
python3 manage.py makemigrations polls # 마이그레이션 파일 생성
python3 manage.py migrate # 마이그레이션
sqlite3 db.sqlite3 # 만들어진 테이블 확인

python3 manage.py migrate polls 0001 # !롤백하고 싶을때

 

 

 

Django admin - 관리자 계정 생성하고 접속하기
장고에서는 admin이라고 하는 관리 사이트를 제공함. 이 사이트는 오직 관리자만이 접속 가능

  • 사용자(시스템 관리자) 만들기
python3 manage.py createsuperuser

 

  • 접속하기
    - 서버 실행 후, 

 

 

 

Django admin - 모델 등록하기

  • 만든 모델을 admin 사이트에서 사용하기 위해, 먼저 모델을 admin에 등록해야함
#admin.py
from django.contrib import admin
from .models import *

admin.site.register(Question)
admin.site.register(Choice)
  • 변경 후, 마이그레이션 파일 생성하고 실행

 

 

Django shell 사용하기

  • Django shell 실행
python3 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()

 

  • 현재 시간 구하기
from datetime import datetime
datetime.now()

from django.utils import timezone
timezone.now()

 

 

 

Django shell - 모델 필터링

# get() 메서드를 사용하여 조건에 해당하는 오브젝트 필터링
>>> Question.objects.get(id=1)
>>> q = Question.objects.get(question_text__startswith='휴가를')
>>> Question.objects.get(pub_date__year=2023) #get으로 여러가지 오브젝트를 가져오려고 한다면 에러발생


# filter() 메서드를 사용하여 조건에 해당하는 오브젝트 필터링
>>> Question.objects.filter(pub_date__year=2023)
>>> 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)


>>> q = Question.objects.get(pk=1)
>>> q.choice_set.all()
>>> print(q.choice_set.all().query)
# 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)

>>> 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)

 

 

 

Django - 모델 메소드

모델 클래스에 사용자 정의 메서드를 추가할 수 있음

  • polls/models.py
class Question(models.Model): # models.Model 상속
    question_text = models.CharField(max_length=200)
    pub_date = models.DateTimeField(auto_now_add=True)
    
    def was_published_recently(self):
        return self.pub_date >= timezone.now() - datetime.timedelta(days=1)
 
    def __str__(self):
        if self.was_published_recently():
            new_badge = 'NEW!!!'
        else:
            new_badge = ''
            
        return f'{new_badge} 제목: {self.question_text}, 날짜 : {self.pub_date}'

 

 

 

레코드 생성하기

  • 새로운 오브젝트를 생성
from polls.models import *

# "커피 vs 녹차" 라는 내용의 새로운 Question 오브젝트를 생성하고, 'q1'이라는 변수에 저장
q1 = Question(question_text = "커피 vs 녹차")

 

  • 오브젝트의 생성시각을 자동으로 설정
# 쉘 상에서 timezone을 활용해 새로운 Question 오브젝트 'q1' 생성시각 설정
from django.utils import timezone
q1.pub_date = timezone.now()


# 코드 상에서 생성시각 자동 설정
pub_date = models.DateTimeField(auto_now=True) # Question 업데이트시마다 시각도 업데이트
pub_date = models.DateTimeField(auto_now_add=True) # Question 새로 생길 때의 시각

 

  • 새로운 오브젝트를 DB에 저장
q1.save()

 

  • q3를 만들고, 필드에 값 넣어보기
q3 = Question(question_text = "abc")
q3.pub_date = timezone.now()
q3.save()

# create() 메서드를 활용해 q3와 연결된 새로운 Choice 오브젝트를 생성하고, choice_text 필드에 값을 넣기
q3.choice_set.create(choice_text="a")
q3.choice_set.create(choice_text="b")

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

# 새로운 Choice 오브젝트를 DB에 저장하기
choice_c.save()

 

 

 

레코드 수정 및 삭제하기

from polls.models import *

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

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

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

#해당 오브젝트에 연결된 Question을 통해서 choice set을 가져오기
>>> choice.queston.choice_set.all()

#해당 오브젝트를 삭제하기
>>> choice.delete()

 

 

 

레코드 필터링

  • polls/models.py
from django.db import models

class Question(models.Model):
    question_text = models.CharField(max_length=200)
    pub_date = models.DateTimeField('date published')
    
    def __str__(self):
        return f'제목: {self.question_text}, 날짜: {self.pub_date}'
        
class Choice(models.Model):
    question = models.ForeignKey(Question, on_delete=models.CASCADE)
    choice_text = models.CharField(max_length=200)
    votes = models.IntegerField(default=0)
    def __str__(self):
        return f'[{self.question.question_text}] {self.choice_text}'
  • shell 상에서
from polls.models import *

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

# question_text 필드 값이 '휴가'로 시작하는 Question 오브젝트를 제외한 오브젝트
# exclude() 메서드
Question.objects.exclude(question_text__startswith='휴가')

 

 

'dev course - DE > TIL' 카테고리의 다른 글

[데브코스] TIL 13일차  (0) 2024.04.12
[데브코스] TIL 12일차  (0) 2024.04.09
[데브코스] TIL 10일차  (0) 2024.04.05
[데브코스] TIL 9일차  (0) 2024.04.04
[데브코스] TIL 8일차  (0) 2024.04.03