TIL: Django 모델 설계 시 의사결정 과정 - Review 모델 사례

2star_·2025년 1월 4일
0

최종 프로젝트

목록 보기
6/32

별점(score) 모델 필드 설정 참고 :DecimalField

TIL: Django 모델 설계 시 의사결정 과정 - Review 모델 사례

오늘은 Django를 활용해 Review 모델을 설계하며, 의사결정 과정과 주요 고려사항을 기록했습니다. ERD 구조를 기반으로 현실적인 요구사항과 비즈니스 로직을 모델링하는 데 중점을 두었고, 각 필드와 메서드가 어떤 이유로 설계되었는지 체계적으로 정리했습니다.


1. ERD 구조에서 모델로의 매핑

🔍 핵심 구조:

ERD에 따라 Review는 다음과 같은 관계를 가지고 있었습니다:

  • UserMany-to-One 관계 (리뷰 작성자는 한 명의 유저)
  • ReviewCommentOne-to-Many 관계 (하나의 리뷰에 여러 댓글 가능)
  • ReviewLikeOne-to-Many 관계 (하나의 리뷰에 여러 좋아요/비추천 가능)

이 구조를 Django ORM으로 옮기면서 ForeignKeyrelated_name을 활용해 연관 관계를 명확히 표현했습니다.


2. 주요 필드 설계

📌 유저와의 관계:

user = models.ForeignKey(
    settings.AUTH_USER_MODEL,
    on_delete=models.SET_NULL,
    null=True,
    blank=True,
    related_name="reviews"
)
  • 의사결정 이유:
    • 유저 삭제 시 리뷰 데이터를 유지하기 위해 SET_NULL 사용.
    • related_name 설정으로 유저 객체에서 리뷰를 쉽게 참조 (user.reviews).

📌 리뷰 내용:

content = models.TextField()
  • 의사결정 이유:
    • 리뷰 내용의 길이에 제한이 없도록 TextField 사용.

📌 게임 식별자 (app_id):

app_id = models.IntegerField()
  • 의사결정 이유:
    • 외부 API(예: Steam)의 게임 ID를 저장하기 위해 추가.
    • 이 필드는 프론트엔드와 백엔드 간 통신에서 중요한 역할을 함.

📌 별점 (score):

score = models.DecimalField(max_digits=2, decimal_places=1, default=1.0)
  • 의사결정 이유:
    • 별점은 0.5 단위로, 최대값이 5.0인 점을 고려해 DecimalField 선택.
    • 정확한 별점 계산을 위해 부동소수점 대신 Decimal 사용.

📌 좋아요/비추천 수 (total_likes, total_dislikes):

total_likes = models.IntegerField(default=0)
total_dislikes = models.IntegerField(default=0)
  • 의사결정 이유:
    • 좋아요/비추천 데이터를 캐싱해 성능 최적화 가능.
    • 추후 필요에 따라 Redis 등의 캐시를 도입할 여지를 남김.

3. 메서드 설계

📌 update_likes_and_dislikes 메서드:

def update_likes_and_dislikes(self):
    self.total_likes = self.likes.filter(is_active=1).count()
    self.total_dislikes = self.likes.filter(is_active=-1).count()
    self.save()
  • 의사결정 이유:
    • 좋아요/비추천 상태는 ReviewLike 모델의 is_active 필드로 관리.
    • 매번 DB를 직접 조회하지 않고 캐싱된 값을 업데이트하도록 설계.

📌 __str__ 메서드:

def __str__(self):
    if self.user:
        nickname = self.user.nickname
    else:
        nickname = "알수없음"
    return f"Review 작성자 : {nickname} - 스팀 게임 번호 : {self.app_id} 평점 : ({self.score})"
  • 의사결정 이유:
    • 콘솔이나 관리자 페이지에서 모델 객체를 직관적으로 확인하기 위함.
    • 유저가 삭제된 경우에도 "알수없음"으로 표시.

4. Meta 옵션

📌 정렬:

class Meta:
    ordering = ["-created_at"]
  • 의사결정 이유:
    • 최신 리뷰가 가장 상단에 표시되도록 기본 정렬 설정.

5. 비즈니스 로직과 확장 가능성

📌 좋아요/비추천 수:

  • ReviewLike 모델에서 is_active 필드를 활용해 중립(0), 좋아요(1), 비추천(-1) 상태를 관리.
  • 추후 Redis와 같은 캐시를 도입하면 성능을 더 개선할 수 있는 구조.

📌 리뷰와 게임 데이터:

  • app_id 필드를 통해 외부 API(예: Steam)와 쉽게 통합 가능.
  • 확장 시, 게임 정보를 별도의 모델로 분리하거나 API 호출을 최적화할 계획.

6. 고려사항 및 개선점

  1. 좋아요/비추천 수 관리:
    • 현재는 직접 DB 조회를 통해 값을 계산하지만, 조회 성능 최적화를 위해 캐시 도입을 고려.
  2. 데이터 무결성:
    • 유저가 삭제된 경우에도 리뷰 데이터가 남아있도록 설계했으나, 일부 시나리오에서는 삭제가 더 적절할 수 있음.

이번 설계를 통해 ERD 구조를 기반으로 현실적인 요구사항을 모델로 구현하는 과정에서, 설계 의도를 명확히 드러내고 성능 및 유지보수 가능성을 고려하는 것이 중요하다는 점을 배웠습니다. 앞으로 다른 모델을 설계할 때도 동일한 접근 방식을 활용해 더 나은 품질의 코드를 작성하고자 합니다.

profile
안녕하세요.

0개의 댓글

관련 채용 정보