Django Shell에서 모델 활용하기

Django에서 shell을 활용하면 데이터베이스에 직접 접근하여 모델 데이터를 조회, 생성, 수정, 삭제할 수 있습니다. 이 글에서는 Django Shell을 사용하여 모델을 다루는 방법을 설명합니다.
Django Shell 실행하기
- Django 프로젝트에서 Shell을 실행하려면 다음 명령어를 입력합니다.
python manage.py shell
모델 조회하기
from polls.models import Question, Choice # 모델 가져오기
# 모든 Question 조회
Question.objects.all()
# 모든 Choice 조회
choices = Choice.objects.all()
choices[0].choice_text # 첫 번째 choice의 텍스트 확인
ForeignKey 관계 활용
- Choice 모델에서 Question을 참조하는 방법과 반대로 Question에서 Choice를 참조하는 방법
# Choice에서 연결된 Question 가져오기
choice = Choice.objects.first()
choice.question.question_text
# Question에서 연결된 Choice 가져오기
question = Question.objects.first()
question.choice_set.all() # 해당 Question에 연결된 모든 Choice 조회
현재 시간 구하기
- Python과 Django에서 현재 시간을 가져오는 방법은 다릅니다.
# Python의 datetime 모듈 사용
from datetime import datetime
datetime.now()
- Django는 글로벌 서비스를 고려하여 타임존을 다루므로 timezone.now()를 사용하는 것이 좋습니다.
from django.utils import timezone
timezone.now() # UTC 기준 현재 시간
레코드 생성하기
q1 = Question(question_text="커피 vs 녹차") # 인스턴스 생성
q1.id # 아직 저장되지 않았으므로 None
q1.save() # DB에 저장
q1.id # 저장 후에는 ID가 할당됨
pub_date 자동 설정
- Question 모델에서 pub_date를 자동으로 설정하려면 models.py에서 다음과 같이 설정할 수 있습니다.
class Question(models.Model):
question_text = models.CharField(max_length=200)
pub_date = models.DateTimeField(auto_now_add=True) # 생성 시 자동으로 현재 시간 저장
- 이제 Question을 생성할 때 pub_date 값을 명시적으로 입력할 필요가 없습니다.
q2 = Question(question_text="abc")
q2.save()
q2.pub_date # 자동으로 설정된 날짜 확인
Choice 생성
q2.choice_set.create(choice_text="a") # 연결된 Choice 생성
- 다른 방식으로도 Choice를 생성할 수 있습니다.
choice_c = Choice(choice_text="c", question=q2)
choice_c.save()
레코드 수정하기
q = Question.objects.last() # 마지막 Question 가져오기
q.question_text += '???' # 텍스트 변경
q.save() # 변경사항 저장
레코드 삭제하기
choice = Choice.objects.last() # 마지막 Choice 가져오기
choice.delete() # 삭제
- 삭제 후에도 choice 변수는 남아 있지만, 데이터베이스에서는 삭제되었습니다.
choice.id # None (삭제되었음을 확인)
- 삭제된 데이터를 다시 저장할 수도 있습니다.
choice.save() # 다시 저장
Django 모델 필터링
Django의 ORM을 사용하면 SQL 쿼리를 직접 작성하지 않고도 모델에서 원하는 데이터를 쉽게 조회할 수 있습니다.
특정 조건의 데이터 조회
- get(): 단일 객체 조회
- get() 메서드는 조건을 만족하는 단 하나의 레코드를 반환합니다.
- 조건에 맞는 레코드가 없거나 여러 개이면 DoesNotExist 또는 MultipleObjectsReturned 예외가 발생합니다.
- 여러 개의 레코드를 조회하려면 filter()를 사용해야 한다.
from polls.models import Question
# id가 1인 레코드 조회
q = Question.objects.get(id=1)
# '휴가를'로 시작하는 question_text를 가진 레코드 조회
q = Question.objects.get(question_text__startswith='휴가를')
# pub_date의 초(second)가 44인 레코드 조회
q = Question.objects.get(pub_date__second=44)
# 주의
Question.objects.get(pub_date__year=2024) # 조건에 맞는 레코드가 여러 개면 에러 발생
- filter(): 여러 개의 레코드 조회
- 조건에 맞는 여러 개의 레코드를 QuerySet 형태로 반환합니다.
# 2024년의 모든 레코드 조회
questions = Question.objects.filter(pub_date__year=2024)
# 해당 조건을 만족하는 레코드 수 카운트
count = questions.count()
- QuerySet 예제
- QuerySet은 데이터베이스에서 SQL 실행을 지연하므로, 실제 데이터를 조회하는 시점에서 SQL이 실행됩니다.
# 모든 레코드 조회
questions = Question.objects.all()
print(questions.count()) # 전체 레코드 개수 출력
# 첫 번째 Question 객체 가져오기
q = questions.first()
# 해당 Question과 연결된 Choice 객체들 조회
choices = q.choice_set.all()
print(choices.count()) # 해당 Question의 Choice 개수 출력
SQL 쿼리 확인
- Django ORM이 내부적으로 어떤 SQL을 생성하는지 확인하려면 query 속성을 사용하면 됩니다.
# 2023년의 모든 레코드를 가져오는 SQL 확인
print(Question.objects.filter(pub_date__year=2023).query)
# 특정 텍스트로 시작하는 레코드의 SQL 확인
print(Question.objects.filter(question_text__startswith='휴가를').query)
- ForeignKey 관계에서도 query 속성을 사용하여 어떤 SQL이 실행되는지 확인할 수 있습니다.
q = Question.objects.get(pk=1)
print(q.choice_set.all().query) # 해당 Question의 모든 Choice 조회 SQL
다양한 필터링 조건
Django는 다양한 조건을 사용하여 데이터를 필터링할 수 있습니다.
- 특정 문자열 포함 (contains)
# '휴가'라는 단어를 포함하는 Question 조회
questions = Question.objects.filter(question_text__contains='휴가')
- 특정 값보다 큰 데이터 조회 (gt)
# votes가 0보다 큰 Choice 조회
choices = Choice.objects.filter(votes__gt=0)
- 데이터 업데이트 (update)
# votes가 0보다 큰 Choice의 votes 값을 0으로 변경
Choice.objects.filter(votes__gt=0).update(votes=0)
- 데이터 삭제 (delete)
# votes가 0인 Choice 삭제
Choice.objects.filter(votes=0).delete()
정규 표현식을 활용한 필터링
- Django ORM에서는 regex를 사용하여 정규 표현식 기반의 검색을 할 수 있습니다.
# '휴가'로 시작하고 '어디'라는 단어가 포함된 Question 조회
questions = Question.objects.filter(question_text__regex=r'^휴가.*어디')
- 비슷한 결과를 filter()를 연속적으로 적용하여 얻을 수도 있습니다.
# '휴가'로 시작하고 '어디'라는 단어를 포함하는 데이터 조회
questions = Question.objects.filter(question_text__startswith='휴가').filter(question_text__contains='어디')'학습 주제 > Django & Django Rest Framework' 카테고리의 다른 글
| Django REST Framework - Serializer & API (0) | 2025.03.10 |
|---|---|
| Django - 예외 처리하기 & Admin (0) | 2025.03.10 |
| Django - 상세 페이지 & 폼 & 커스터마이징 (0) | 2025.03.10 |
| Django - 모델 관계 기반 필터링 & 뷰 & 템플릿 (0) | 2025.03.10 |
| Django - Model (0) | 2025.03.09 |