Django - 모델 관계 기반 필터링 & 뷰 & 템플릿

2025. 3. 10.·학습 주제/Django & Django Rest Framework
 

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
'학습 주제/Django & Django Rest Framework' 카테고리의 다른 글
  • Django - 예외 처리하기 & Admin
  • Django - 상세 페이지 & 폼 & 커스터마이징
  • Django Shell에서 모델 활용하기
  • Django - Model
굥여9
굥여9
9idryd 님의 블로그 입니다.
  • 굥여9
    문과의 개발
    굥여9
  • 전체
    오늘
    어제
    • 분류 전체보기 (114)
      • 학습 주제 (86)
        • 자료구조와 알고리즘 (8)
        • HTML & 웹크롤링 (4)
        • 데이터 시각화 (4)
        • Django & Django Rest Framew.. (11)
        • AWS 클라우드 (6)
        • SQL & 데이터 웨어하우스 (11)
        • 데이터파이프라인과 Airflow (12)
        • Docker & K8S (8)
        • DBT (4)
        • CI & CD (1)
        • 빅데이터 처리와 Spark (12)
        • Kafka & Spark Streaming (5)
        • 보안 엔지니어링 (0)
      • 구름 프로펙트 클라우드 엔지니어링 (0)
        • [Monolithic] 서비스의 기초와 설계 (0)
        • [MSA & EDA] 비동기 전환과 정합성 (0)
        • [Cloud Native] K8s 기반 인프라와 .. (0)
      • 프로그래머스 데브코스 데이터 엔지니어링 (4)
      • 개발 기록 (24)
        • 일일 (24)
        • 주간 (0)
      • 회고 (0)
  • 블로그 메뉴

    • 홈
    • 태그
    • 방명록
  • 링크

    • 깃허브
  • 공지사항

  • 인기 글

  • 최근 댓글

  • 최근 글

  • hELLO· Designed By정상우.v4.10.3
굥여9
Django - 모델 관계 기반 필터링 & 뷰 & 템플릿
상단으로

티스토리툴바