bash
overview/views.py
└─ commit_list_api(request)
python
owner = request.GET['owner']
repo = request.GET['repo']
username= request.GET.get('username')
count = int(request.GET.get('count', 20))
db_commits = get_stored_commits(owner, repo, username, count)
if not db_commits: # ❶ DB에 없으면
raw_commits = fetch_detailed_commit_history( # ❷ GitHub GraphQL 호출
owner, repo, username, count)
return JsonResponse({'commits': raw_commits})
else: # ❸ DB에 있으면
serialized = _serialize(db_commits) # ❹ Django → GitHub 형식 변환
return JsonResponse({'commits': serialized})
get_stored_commits()
내부 원리 (utils.py)python
def get_stored_commits(owner, repo, username=None, count=20):
# (1) Repository FK 찾기
repository = Repository.objects.get(owner=owner, name=repo)
# (2) Commit 테이블 필터링
qs = Commit.objects.filter(repository=repository)
if username:
qs = qs.filter(author=username)
# (3) 최신순 정렬 + 슬라이싱
return qs.order_by('-committed_date')[:count]
단계 | SQL로 번역하면 | 비고 |
---|---|---|
(1) | SELECT id FROM overview_repository WHERE owner=… AND name=… |
없으면 DoesNotExist 예외 → 상위에서 except Repository.DoesNotExist: 처리 |
(2) | SELECT * FROM overview_commit WHERE repository_id=X [AND author='username'] |
|
(3) | … ORDER BY committed_date DESC LIMIT <count> |
최신 커밋 n개 |
성공 조건 : 위 쿼리 결과가 하나라도 있으면 “캐시 Hit”.
fetch_detailed_commit_history()
로 GitHub 재조회GraphQL Query:
graphql
repository(owner:"{owner}", name:"{repo}") {
defaultBranchRef {
target { ... on Commit {
history(first: {count*3}) { ... }
내부 과정
requests.post()
로 GitHub GraphQL 호출.username
필터(로그인 · name · email 매칭).save_to_db
기본값 True → 곧바로 save_commits_to_db()
실행 → Repository/Commit/CommitFile row 삽입.filtered_commits
) 그대로 반환 → API 응답에 사용.즉 첫 캐시 Miss 시 네트워크를 타면서 동시에 DB 캐싱을 끝냅니다.
python
commit_dict = {
'oid' : commit.sha,
'author' : {
'name' : commit.author,
'user' : {'login': commit.author}
},
'message' : commit.message,
'committedDate': commit.committed_date.isoformat(),
'additions' : commit.additions,
'deletions' : commit.deletions,
'changedFiles' : commit.changed_files
}
CommitFile
은 필요할 때 /api/commits/<sha>/
상세 API에서 별도로 직렬화.