Home 22/05/19/목 Vue 응용, 1학기 마지막 프로젝트- API
Post
Cancel

22/05/19/목 Vue 응용, 1학기 마지막 프로젝트- API

220519 Today I learned!

  • 1학기 마지막 프로젝트

1. Fact

(1) 1학기 마지막 프로젝트

  • 트레일러 페이지 API
  • profile_imge 필드 수정
  • 회원 가입 시 기입한 정보가 DB에 저장되지 않는 오류를 수정했다.
  • MovieReview API
    • 최신순, 인기순 필터
    • CRUD
    • 프로필 페이지, 회원정보 수정 API
  • 영화 추천 API
    • 최근 개봉 인기 영화 (50일 이내 개봉, 인기도 순으로 정렬)
    • 요즘 제일 관심 받는 영화 (30일내에 작성된 리뷰가 많은 영화)
    • 계절 추천 영화 (계절별 특정의 인기 있는 영화를 추천)
  • Vue 초기 셋팅
  • 프로젝트 깃허브
  • 프로젝트 노션


2. Feeling

어제 구현하지 못한 회원 탈퇴를 구현했다. settings.py의 installed app에 빠진 내역이 있어서 오류가 발생했던 것이다 ㅠㅠ 요즘 왜맞틀~을 왜치면서 오류를 찾는 데 바쁘다. 그래도 오늘 백엔드는 끝이났고 내일부터 프론트 엔드를 시작할 것 같다. 과연 내가 기획했던 것들을 전부 구현할 수 있을지 모르겠지만,,,,

Vue에 대한 실력이 미숙한 것은 누구보다 알지만 프로젝트를 하면서 많이 배워갈 수 있을 거라는 생각이 든다.


3. Finding

django orm은 신이다….

  • annotate로 생성한 열을 filter로 조건을 줄 수 있다. 또한, __를 활용하면 역참조 모델의 다른 필드에 접근할 수 있다.
1
2
3
4
5
6
7
8
now = timezone.now()
movies = Movie.objects.annotate(
    review_count=Count(
        'review', distinct=True, filter = Q(
            review__created_at__range=[now-timedelta(days=30), now]
        ))).order_by('-review_count')[:21]
serializer = MovieListSerializer(movies, many=True)
return Response(serializer.data)

annotate를 통해 review_count column을 생성하고 생성한 열을 created_at 범위로 filter설정을 준다.

그 결과, 30일 이내 reivew를 작성한 수가 많은 영화에 대한 데이터를 받아올 수 있다.


  • order_by('?')는 랜덤으로 정렬한 결과를 도출한다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
        now = int(timezone.now().strftime('%m'))
        if now == 3 or now == 4 or now == 5:
            season = 'spring'
        elif now == 6 or now == 7 or now == 8:
            season = 'summer'
        elif now == 9 or now == 10 or now == 12:
            season = 'fall'
        else:
            season = 'winter'
        season_code = {
            'spring': 10749, 'summer': 27, 'fall': 12, 'winter': 14
        }
        genre_id = season_code.get(season)
        movies = Movie.objects.filter(genre_ids=genre_id, popularity__gt=99).order_by('?')[:21]
        serializer = MovieListSerializer(movies, many=True)
        return Response(serializer.data)

너무 인기도로만 정렬 하면 겹치는 추천영화가 많을 것을 예상했다. 그래서 인기도의 하한선을 정한뒤, 랜덤으로 정렬하여 데이터를 보낸다.


  • ~Q()은 not~과 같다.
1
2
3
movie = Movie.objects.filter(~Q(trailer_youtube_key='nothing') ,popularity__gt=99).order_by('?')
serializer = MovieTrailerSerializer(movie, many=True)
return Response(serializer.data)    

~Q(trailer_youtube_key='nothing' => trailer_youtube_key가 있는 경우를 의미한다. (데이터를 받을 때 조건에 맞는 데이터가 없으면 ‘nothing’를 저장하기 때문이다.)

즉, trailer_youtube_key가 있고 인기도가 99를 넘는 영화를 랜덤으로 정렬한다.


URL을 조심하자…!

/api/v1/accounts/login, signup이 되지 않아 골치가 많이 아팠다. 갑자기 자격 인증데이터(authentication credentials)가 제공되지 않아서 접근할 수 었다는 오류가 발생했다. login과 signup단계에서는 당연히 토근이 생성되지 않았기 때문에 토큰을 가져올 수 없는데, 왜 이럴까 고민했다.

그런데! 나의 빛과 소금과 같은 프엔 스터디 친구들이 도움을 주었다.

1
2
3
4
5
6
7
8
9
10
11
urlpatterns = [
    path('admin/', admin.site.urls),
    path('api/v1/movie/', include('movies.urls')),
    path('api/v1/article/', include('articles.urls')),
    path('api/v1/accounts/', include('dj_rest_auth.urls')), 
    path('api/v1/accounts/signup/', include('dj_rest_auth.registration.urls')),
    
    # 프로필로 가는 url 뒤에 <str:username>이 붙을 예정이다. 
    path('api/v1/accounts/', include('accounts.urls')),

]

여기서 중요한 것은 path('api/v1/accounts/', include('accounts.urls'))를 가장 맨뒤로 보내야 한다는 것이다.

만약 상단에 배치한다면, 해당 url은 뒤에 <str:username>이 붙기 때문에 api/v1/accounts/login 혹은 api/v1/accounts/signip/의 뒷부분이 문자열로 인식된다.

그 결과, 내가 생각했던 view함수가 실행되지 않을 것이다. 또한, 위의 url의 문제점은 signup이라는 아이디를 가진 사람은 자신의 프로필 페이지에 절대 가지 못한다. 😅 그래서 결국 api/v1/accounts/profile/<str:username>으로 수정했다.


4. Future Action & Feedback

Future Action진행 상황Feedback
DOM을 깨우치다pause 🤦‍♀️잠시 중단!
why 리액트?Not Start🌙 


This post is licensed under CC BY 4.0 by the author.