Repository: sparcs-kaist/otlplus

Issue:
[CHORE] 졸업플래너 신규 model의 serialize결과 캐싱
## 동기

**Is your feature request related to a problem? Please describe.**

OTL의 주요 모델에는 캐시가 구현되어 있으나 졸업플래너에서 새로 생성된 model은 아직 캐싱이 적용되어 있지 않습니다.
베타 출시 때는 우선 임시로 그대로 출시하였지만 캐시 도입이 필요합니다.
특히 트랙 부분은 페이지 접속 시에 로딩되고 한번에 많은 양이 로드되기 때문에 성능이 상당히 저하될 여지가 있습니다.

## 설명

**Describe the solution you'd like.**

A clear and concise description of what you want to happen.

## 스크린샷

(OPTIONAL) If applicable, add screenshots to help explain your feature request.

## 개발 환경

- OS: [e.g. macOS]
- ```python --version```:
- ```node --version```:

## 테스트 환경

(OPTIONAL)

- Device: [e.g. iPhone6]
- OS: [e.g. iOS8.1]
- Web Version: [e.g. 1.1.0]

## 추가 정보

(OPTIONAL) Add any other context or screenshots about the feature request here.



Discussion:

Resolving patch:
diff --git a/apps/graduation/models.py b/apps/graduation/models.py
--- a/apps/graduation/models.py
+++ b/apps/graduation/models.py
@@ -1,4 +1,5 @@
 from django.db import models
+from django.core.cache import cache
 
 from apps.subject.models import Department
 
@@ -26,7 +27,15 @@ class GeneralTrack(models.Model):
     class Meta:
         unique_together = [["start_year", "is_foreign"], ["end_year", "is_foreign"]]
 
+    def get_cache_key(self):
+        return "generaltrack:%d-%d-%s" % (self.start_year, self.end_year, self.is_foreign)
+
     def to_json(self):
+        cache_id = self.get_cache_key()
+        result_cached = cache.get(cache_id)
+        if result_cached is not None:
+            return result_cached
+
         result = {
             "id": self.id,
             "start_year": self.start_year,
@@ -44,6 +53,8 @@ def to_json(self):
             "humanities_doublemajor": self.humanities_doublemajor,
         }
 
+        cache.set(cache_id, result, 60 * 60)
+
         return result
 
 
@@ -60,7 +71,15 @@ class MajorTrack(models.Model):
     class Meta:
         unique_together = [["start_year", "department"], ["end_year", "department"]]
 
+    def get_cache_key(self):
+        return "majortrack:%d-%d-%d" % (self.start_year, self.end_year, self.department.id)
+
     def to_json(self):
+        cache_id = self.get_cache_key()
+        result_cached = cache.get(cache_id)
+        if result_cached is not None:
+            return result_cached
+
         result = {
             "id": self.id,
             "start_year": self.start_year,
@@ -71,6 +90,8 @@ def to_json(self):
             "major_elective": self.major_elective,
         }
 
+        cache.set(cache_id, result, 60 * 60)
+
         return result
 
 
@@ -95,7 +116,15 @@ class AdditionalTrack(models.Model):
     class Meta:
         unique_together = [["start_year", "type", "department"], ["end_year", "type", "department"]]
 
+    def get_cache_key(self):
+        return "additionaltrack:%d-%d-%s-%d" % (self.start_year, self.end_year, self.type, self.department.id if self.department else 0)
+
     def to_json(self):
+        cache_id = self.get_cache_key()
+        result_cached = cache.get(cache_id)
+        if result_cached is not None:
+            return result_cached
+
         result = {
             "id": self.id,
             "start_year": self.start_year,
@@ -106,4 +135,6 @@ def to_json(self):
             "major_elective": self.major_elective,
         }
 
+        cache.set(cache_id, result, 60 * 60)
+
         return result


Test patch: