주절주절 서론
이번 포스팅에서는 지난 포스팅에 이어 Django의 shell을 통해 model을 다루는 방법 중 조건에 해당하는 오브젝트를 필터링하는 방법에 대해 알아보겠습니다!
길지 않은 내용이지만, 쉘에서 자주 사용되는 내용이니, 읽어보시면 도움이 되실거에요!
지난 포스팅들을 기반으로 진행하는 내용이니, 이전 Django 포스팅도 한 번씩 읽으시는 걸 추천드려요!
1. Django shell 실행
$ python manage.py shell
2. 모델 Import
앞선 포스팅에서 polls라는 app을 만들고, 그 app에 Question, Choice 모델을 만들어 주었으니, Import하여 불러오도록 하겠습니다!
>>> from polls.models import *
>>> Question
<class 'polls.models.Question'>
>>> Choice
<class 'polls.models.Choice'>
이제 해당 모델에서 원하는 오브젝트. 값을 가져오는 방법에 대해 알아보도록 하겠습니다!
3. 원하는 값을 가져오자! - Get()!
# id 값을 통해 원하는 오브젝트 찾기!
>>> Question.objects.get(id=3)
<Question: 제목: 커피 vs 녹차, 날짜: 2024-10-07 06:21:32.035790+00:00>
# question_text가 '커피'로 시작하는 오브젝트 찾기!
>>> Question.objects.get(question_text__startswith='커피')
<Question: 제목: 커피 vs 녹차, 날짜: 2024-10-07 06:21:32.035790+00:00>
# 그럼 '커피'로 시작하는 오브젝트를 찾는 get 코드를 쿼리로 바꿔보면?
>>> print(Question.objects.get(question_text__startswith='커피').query)
Traceback (most recent call last):
File "<console>", line 1, in <module>
AttributeError: 'Question' object has no attribute 'query'
위처럼 get()을 통해 조건에 맞는 오브젝트를 찾을 수 있습니다.
하지만, 마지막 코드를 보면, get() 코드를 쿼리로 변경하려 했을 때! 오류가 발생하는 모습을 확인할 수 있습니다!
이유는?
이유는, get() 메소드는 단일 객체를 반환하기에, query를 사용할 수 없다고 합니다..ㅠㅠ
그렇다면 쿼리를 뽑을 수 있는 방법이 없을까요??
4. 단일 값도 쿼리로! 원하는 값을 가져오자! - filter()!
위의 문제를 해결할 수 있는 filter() 메소드가 존재합니다!
앞서 오류가 발생했던 '커피'로 시작하는 오브젝트를 찾아보겠습니다.
>>> Question.objects.filter(question_text__startswith='커피')
<QuerySet [<Question: 제목: 커피 vs 녹차, 날짜: 2024-10-07 06:21:32.035790+00:00>]>
>>> print(Question.objects.filter(question_text__startswith='커피').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" LIKE 커피% ESCAPE '\'
쿼리로 올바르게 변환된 모습을 확인할 수 있었습니다!
5. get() vs filter() ?
그렇다면, query 변환이 가능한 filter()가 더 좋은 게 아닌가?? 하는 의문이 생길 수 있습니다.
하지만, 그렇지 않습니다!!
get()은 단일 객체를 반환하며, 결과가 없을 경우 DoesNotExist, 결과가 여러 개일 경우 MultipleObjectsReturned 예외를 발생시켜, 코드를 예외처리하거나, 단일 객체를 처리하는 경우에 유리합니다.
또한, filter()는 여러 객체를 반환하며, 결과가 없을 경우 빈 queryset을 반환하기에, 오브젝트의 정확한 수를 모를 때 사용하기 유리합니다!
그렇기에 상황에 맞는 메소드를 사용하는 것이 좋겠죠??
6. 연관된 객체에서 값 찾기
앞선 포스팅에서 저희는 Question과 Question을 참조하는 Choice. 두 개의 모델을 만들었습니다!
그렇다면 Choice는 Question의 pk(기본키)를 fk(외래키)로 갖게될텐데, 이런 경우에 Question에서 자신을 참조하는 Choice를 모두 찾는 방법에 대해서 알아보겠습니다!
>>> Choice.objects.filter(question__question_text__startswith='abc')
<QuerySet [<Choice: 질문: abc???, 답변 a>, <Choice: 질문: abc???, 답변 b>, <Choice: 질문: abc???, 답변 c>]>
Choice를 filter할 경우 filter 조건에, question__question_text__startswith='abc'를 통해 abc로 시작하는 question_text를 값으로 갖고있는 Question을 참조하는 Choice를 모두 가져올 수 있었습니다!
말이 조금 복잡하지만, 사진과 코드의 결과를 보시면 이해하실 수 있을 거에요!
마치며..
더 많은 쉘을 다루는 함수, 코드가 있지만, 모두 설명하기에는 역부족이기에 참고하실 수 있는 Django 문서를 첨부로 Django Shell에 대한 설명을 마치겠습니다!
https://docs.djangoproject.com/en/5.1/topics/db/queries/
오늘 포스팅도 봐주셔서 감사합니다!
'Django' 카테고리의 다른 글
[Django] Django - 5 (View & Template) (0) | 2024.10.10 |
---|---|
[Django] Django - 3 (Handling models in shell - Part 1) (2) | 2024.10.08 |
[Django] Django - 2 (Admin) (0) | 2024.10.08 |
[Django] Django - 1 (개념 및 실습) (2) | 2024.10.07 |