터칭 데이터
장고(Django) 모델 관계기반 필터링 본문
학습에 앞서
먼저 학습에 앞서 위와 같이 choice들이 어떤 question에 대한 것인지 쉽게 알아볼 수 있도록
polls/models.py에서
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}' # 이곳을 수정
와 같이 __str__의 내용을 수정해주도록 합시다.
그리고 학습을 위해 위와 같이 대괄호 [ ~ ] 안의 question에 대한 7가지의 choice들을 입력해주세요.
우리는 지난 시간에 데이터들을 어떻게 입력하는지
2가지 방법을 살펴보았습니다.
1. (모델의 row).choice_set.create() 메서드
2. 모델객체() 선언
그리고 __str__을 변경하며 모델이 변경되었으므로 쉘(shell)을 꼭 다시 한번 껐다 켜주시는걸 잊지 마세요
모델 관계를 기반으로 데이터 불러오기
위는 Choice 데이터들입니다.
빨간색은 휴가 계획 question을 참조하는 choice들이고
파란색은 휴가 장소 question을 참조하는 choice들입니다.
위의 빨간색과 파란색 박스의 choice들을 한번에 쿼리셋(Query Set)으로 불러오는 방법이 있을까요?
네 있습니다.
>>> from polls.models import *
>>> Choice.objects.filter(question__question_text__startswith='휴가')
<QuerySet [<Choice: [휴가를 어디서 보내고 싶으세요?] 바다>, <Choice: [휴가를 어디서 보내고 싶으세요?] 산>, <Choice: [휴가를 어디서 보내고 싶으세요?] 도심 호캉스>, <Choice: [휴가를 가실 계획인가요?] 네>, <Choice: [휴가를 가실 계획인가요?] 아니오>]>
Choice 객체를 이용해 filter()에 명령을 줬는데요.
하나하나 살펴보면
quetion을 통해 조건을 정하는데(qeustion)
question_text가(__question_text)
휴가로 시작하는(__startswith='휴가')
데이터들을 가져오라는 뜻입니다.
Choice 객체의 외래키(Foreign Key)를 통해 접속할 수 있는 다른 테이블의 내용을 읽어서 활용하고 싶다면
filter(모델명(외래키)__필드명__조건문)를 적어주시면 됩니다.
__는 언더바 2개임을 주의하세요.
자세히 알아보기 위해 쿼리문을 살펴보면
>>> print(Choice.objects.filter(question__question_text__startswith='휴가').query)
SELECT
"polls_choice"."id",
"polls_choice"."question_id",
"polls_choice"."choice_text",
"polls_choice"."votes"
FROM
"polls_choice" INNER JOIN "polls_question"
ON ("polls_choice"."question_id" = "polls_question"."id")
WHERE "polls_question"."question_text" LIKE 휴가% ESCAPE '\'
filter()에서 첫부분에 주어진 question을 이용해 choice와 question을 INNER JOIN을 한 테이블에서 데이터들을 가져오고 있습니다. Choice만으로는 question_text가 휴가인 경우를 알 수 없기 때문이죠
Exclude
exclude()는 filter()의 반대라고 생각하면 됩니다.
>>> Question.objects.filter(question_text__startswith='휴가')
<QuerySet [<Question: 제목: 휴가를 어디서 보내고 싶으세요?, 날짜: 2023-10-31 14:19:40+00:00>, <Question: 제목: 휴가를 가실 계획인가요?, 날짜: 2023-11-02 03:36:12.245190+00:00>]>
>>> Question.objects.exclude(question_text__startswith='휴가')
<QuerySet [<Question: 제목: 가장 좋아하는 디저트는?, 날짜: 2023-10-31 14:22:37+00:00>, <Question: 제목: 커피 vs 녹차, 날짜: 2023-11-01 05:37:56.580508+00:00>, <Question: 제목: abc???, 날짜: 2023-11-01 05:51:02.905096+00:00>]>
filter의 쿼리문
>>> 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 '\'
exclude의 쿼리문
>>> print(Question.objects.exclude(question_text__startswith='휴가').query)
SELECT
"polls_question"."id", "polls_question"."question_text", "polls_question"."pub_date"
FROM "polls_question"
WHERE NOT ("polls_question"."question_text" LIKE 휴가% ESCAPE '\')
WHERE가 WHERE NOT이라는 차이가 있습니다.
위에서 어떤 모델 객체의 외래키를 이용한 모델 관계 기반 필터링에서 filter 대신 exclude를 이용해 필터링을 해보면 어떤 결과가 뜰까요?
>>> Choice.objects.exclude(question__question_text__startswith='휴가')
<QuerySet [<Choice: [커피 vs 녹차] 커피>, <Choice: [커피 vs 녹차] 녹차>]>
위와 같이 휴가로 시작하지 않는 choice들만 뜨는데요
우리가 위에서 봤던 빨간색과 파란색 박스 그 어디에도 포함되지 않는 choice들만 선택된 것을 볼 수 있습니다.
'장고 (Django)' 카테고리의 다른 글
왜 장고는 View 메서드에서 request를 파라미터로 가질까? (0) | 2023.11.02 |
---|---|
장고(Django) 모델 메소드 (0) | 2023.11.02 |
장고(Django) 모델 필터링(Model Filtering) 2 (0) | 2023.11.01 |
장고(Django) 모델 필터링(Model Filtering) (0) | 2023.11.01 |
장고(Django) 쉘에서 데이터 수정하고 삭제하기 (0) | 2023.11.01 |