Django 모델 관계 기반 필터링
ForeignKey를 이용한 필터링
Django의 ORM에서는 ForeignKey를 활용하여 연관된 객체를 쉽게 조회할 수 있습니다.
from polls.models import Choice
# '휴가'로 시작하는 Question의 모든 Choice 가져오기
choices = Choice.objects.filter(question__question_text__startswith='휴가')
print(choices)
# SQL 쿼리 확인
print(choices.query)
- question__question_text__startswith='휴가'를 사용
- Choice 모델에서 ForeignKey로 연결된 Question 모델의 question_text 값을 필터링
exclude를 이용한 필터링
- exclude() 메서드는 특정 조건을 제외한 데이터를 조회할 때 유용합니다.
- exclude()는 filter()와 반대로 동작하여 특정 조건을 만족하지 않는 데이터를 조회합니다.
from polls.models import Question, Choice
# '휴가'로 시작하는 Question 조회
questions = Question.objects.filter(question_text__startswith='휴가')
# '휴가'가 포함되지 않은 Question 조회
excluded_questions = Question.objects.exclude(question_text__startswith='휴가')
# '휴가'가 포함되지 않은 Question의 Choice 조회
excluded_choices = Choice.objects.exclude(question__question_text__startswith='휴가')
모델 메서드 활용
Django 모델 클래스 내부에 메서드를 추가하면 객체에 대한 유용한 기능을 정의할 수 있습니다.
save() 메서드 활용
- 모델의 save() 메서드를 사용하여 데이터를 저장하고 변경할 수 있습니다.
c = Choice.objects.first()
print(c.votes) # 기존 투표 수 확인
c.votes = 0 # 투표 수 변경
c.save() # 변경된 값 저장
print(c.votes) # 변경 확인
was_published_recently() 메서드 추가
- 게시된 Question이 최근 생성된 것인지 판별하는 메서드를 추가할 수 있습니다.
- pub_date가 하루 이내인지 확인하여 True 또는 False를 반환합니다.
from django.utils import timezone
import datetime
class Question(models.Model):
question_text = models.CharField(max_length=200)
pub_date = models.DateTimeField('date published')
def was_published_recently(self):
return self.pub_date >= timezone.now() - datetime.timedelta(days=1)
was_published_recently() 활용 예제
q = Question.objects.first()
print(q.was_published_recently()) # False (오래된 질문)
# 새로운 질문 추가
new_q = Question(question_text='새로운 질문', pub_date=timezone.now())
new_q.save()
print(new_q.was_published_recently()) # True (최근 생성된 질문)
NEW 배지 추가
- 최근에 게시된 질문에는 NEW!!! 배지를 붙여서 표시할 수도 있습니다.
class Question(models.Model):
question_text = models.CharField(max_length=200)
pub_date = models.DateTimeField('date published')
def was_published_recently(self):
return self.pub_date >= timezone.now() - datetime.timedelta(days=1)
def display_question(self):
new_badge = 'NEW!!! ' if self.was_published_recently() else ''
return f'{new_badge}제목: {self.question_text}, 날짜: {self.pub_date}'
- display_question() 메서드를 호출하면 최근에 게시된 질문에 NEW!!!가 붙은 문자열을 반환합니다.
q = Question.objects.first()
print(q.display_question())
뷰(Views)와 템플릿(Templates)
Django에서는 Model-View-Template(MVT) 패턴을 사용하여 데이터를 처리하고 화면에 표시합니다
뷰(Views)란?
- Django의 뷰(view) 는 모델에서 데이터를 가져와 사용자에게 전달하는 역할을 합니다.
- HTTP 요청을 받아서 처리하고, 응답을 반환하는 함수 또는 클래스로 정의됩니다.
기본 뷰 예제
- 가장 최근에 만들어진 Question 객체 5개를 조회하여 문자열로 출력하는 뷰
from django.http import HttpResponse
from .models import Question
def index(request):
latest_question_list = Question.objects.order_by('-pub_date')[:5]
output = ', '.join([q.question_text for q in latest_question_list])
return HttpResponse(output)
Query 확인
print(Question.objects.order_by('-pub_date')[:5].query)
템플릿(Templates)
템플릿이란?
- 템플릿(template) 은 데이터를 HTML로 표현하는 기능을 합니다.
- 모델에서 가져온 데이터를 보기 좋은 형식으로 변환할 수 있습니다.
뷰에서 템플릿을 사용하는 방법
- 뷰에서 HTML 템플릿을 사용하려면 render 함수를 활용합니다.
from django.shortcuts import render
def index(request):
return render(request, 'polls/index.html')
데이터를 템플릿으로 전달하기
- 뷰에서 가져온 데이터를 템플릿에 전달하려면 context를 사용합니다.
from django.shortcuts import render
from .models import Question
def index(request):
latest_question_list = Question.objects.order_by('-pub_date')[:5]
context = {'first_question': latest_question_list[0]}
return render(request, 'polls/index.html', context)
- 템플릿 코드 (index.html)
<ul>
<li>{{ first_question }}</li>
</ul>
템플릿에서 제어문 사용하기
템플릿 문법
- 변수 출력: {{ 변수명 }}
- 제어문: {% if %}, {% for %}, {% endif %}, {% endfor %} 등
여러 개의 데이터 출력하기
- 뷰에서 여러 개의 Question 데이터를 템플릿으로 전달합니다.
뷰 코드 (views.py)
context = {'questions': latest_question_list}

템플릿 코드 (index.html)
{% if questions %}
<ul>
{% for question in questions %}
<li>{{ question }}</li>
{% endfor %}
</ul>
{% else %}
<p>No questions available.</p>
{% endif %}
- 주의
- Django 템플릿에서는 리스트 인덱스 접근 방식이 Python과 다릅니다.
- questions[0] 대신 questions.0을 사용하면 오류가 발생합니다.
- 따라서 반복문을 사용하여 데이터를 출력하는 것이 일반적입니다.
'학습 주제 > 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 Shell에서 모델 활용하기 (0) | 2025.03.09 |
| Django - Model (0) | 2025.03.09 |