super()
자식 클래스에서 부모 클래스의 메서드나 속성을 호출할 때 사용
- 상속 관계에서 자식 클래스가 부모의 기능을 그대로 쓰거나
- 기능을 확장(Override)하고 싶을 때 핵심적인 역할
모델의 save() 메서드 재정의
- 데이터가 데이터베이스에 저장되기 직전이나 직후에 특정 로직을 자동으로 실행하고 싶을 때 사용
super() 사용 이유
- save는 DB와 통신하는 복잡한 로직을 담고 있음, 이를 우리가 직접 다 짤 수 없기에
- "슬러그만 내가 만들 테니, 나머지는 원래 장고가 하던 대로 저장해줘!"라고 요청하는 것
from django.db import models
from django.utils.text import slugify
class Post(models.Model):
title = models.CharField(max_length=100)
slug = models.SlugField(unique=True, blank=True)
def save(self, *args, **kwargs):
if not self.slug:
self.slug = slugify(self.title)
super().save(*args, **kwargs)
클래스 기반 뷰(CBV)에서 컨텍스트 추가
- 화면(Template)에 기본 데이터 외에
- 추가적인 정보(예: 인기 태그 목록, 광고 등)를 넘겨주고 싶을 때 사용
super() 사용 이유
- ListView는 이미 페이지네이션 처리나 게시글 목록 가져오기 등 많은 일을 알아서 하고 있음
super() 를 통해 기본 데이터를 챙긴 뒤, 내가 원하는 것만 한두 개 더 얹어서 보내는 것
from django.views.generic import ListView
from .models import Post, Tag
class PostListView(ListView):
model = Post
template_name = 'blog/list.html'
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
context['all_tags'] = Tag.objects.all()
return context
DRF 시리얼라이저의 to_representation 커스텀
- API 응답 결과의 데이터 형식을 최종적으로 가공하고 싶을 때 사용
super() 사용 이유
- 시리얼라이저가 모델의 모든 필드를 파이썬 딕셔너리로 바꾸는 과정은 매우 번거로움
super() 로 그 과정을 편하게 끝낸 결과물만 받아서 마지막에 살짝 수정만 하는 효율적
from rest_framework import serializers
class PostSerializer(serializers.ModelSerializer):
class Meta:
model = Post
fields = '__all__'
def to_representation(self, instance):
representation = super().to_representation(instance)
representation['created_at'] = instance.created_at.strftime('%Y년 %m월 %d일')
return representation
빈번하게 사용되는 내장 메서드
getattr() & setattr()
setattr(obj, name, value)
- 서비스에서 전달받은 validated_data의
- 여러 필드를 한꺼번에 업데이트할 때 사용
getattr(obj, name, default)
- 특정 속성의 값을 동적으로 가져올 때 유용합니다.
set()
- 순서가 없고 중복을 허용하지 않는 자료형을 만듭니다.
enumerate()
- 반복문(for문)을 돌릴 때 현재 몇 번째 루프인지 인덱스 번호가 필요할 때 사용
range(len(list)) 를 쓰는 것보다 훨씬 파이썬답고 깔끔한 방법
posts = ['첫 번째 글', '두 번째 글', '세 번째 글']
for index, title in enumerate(posts, start=1):
print(f"{index}번 게시글 제목: {title}")
all() & any()
- 리스트나 튜플 같은 반복 가능한 객체 내부의 요소들이 모두 참인지(all)
- 혹은 하나라도 참인지(any) 검사할 때 사용
- 여러 필드의 유효성을 한꺼번에 검사할 때 매우 유용
all(iterable) : 모든 요소가 참이어야 True 반환
any(iterable) : 하나라도 참이면 True 반환
required_fields = [post.title, post.content, post.author]
if all(required_fields):
print("저장 가능")
zip() (여러 리스트를 하나로 묶기)
- 여러 개의 리스트를 병렬로 묶어서 하나씩 꺼내 쓸 때 사용
- 예를 들어 제목 리스트와 내용 리스트를 동시에 순회해야 할 때 유용
titles = ["제목1", "제목2"]
contents = ["내용1", "내용2"]
for title, content in zip(titles, contents):
print(f"매칭: {title} - {content}")