Django에서의 Projects vs. Apps
- 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
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 |