ユーザ依存の評価値の取得
バックエンド
マッパー
src/backend/api/online/mappers.py
class MovieMapper:
def __init__(self, obj, rating=None): # <- ratingを追加
self.obj = obj
self.rating = rating # <- 追加
def as_dict(self):
movie = self.obj
genres = [GenreMapper(movie_genre.genre).as_dict() for movie_genre in movie.movie_genres.all()]
rating = RatingMapper(self.rating).as_dict() if self.rating else None # <- 追加
return {
'movie_id': movie.movie_id,
'title': movie.title,
'year': movie.year,
'genres': genres,
'imdb_id': movie.imdb_id,
'tmdb_id': movie.tmdb_id,
'rating': rating, # <- 追加
}
...(略)...
ビュー
src/backend/api/online/views.py
...(略)...
class MoviesView(APIView):
"""映画リストビュー"""
permission_classes = (AllowAny,)
def get(self, request, format=None):
"""
映画リストを取得する。
Responses
---------
movies : json
映画リスト
"""
# ↓追加
# ユーザ認証
user = _get_user(request)
# ↑追加
# オブジェクトの取得
movies = Movie.objects.order_by('?')[:20]\
.prefetch_related('movie_genres__genre')
# ↓追加
rating_map = {}
if user:
rating_map = {
rating.movie_id: rating for rating in UserMovieRating.objects.filter(user=user)
}
# ↑追加
# レスポンス
movies_dict = [
MovieMapper(
movie, # <- 「,」を追加
rating=rating_map.get(movie.movie_id) # <- 追加
).as_dict() for movie in movies
]
data = {
'movies': movies_dict,
}
return Response(data, status.HTTP_200_OK)
class MovieView(APIView):
"""映画ビュー"""
permission_classes = (AllowAny,)
def get(self, request, movie_id, format=None):
"""
映画オブジェクトを取得する。
Attributes
----------
movie_id : int
映画ID
Responses
---------
movie : json
映画オブジェクト
"""
# ↓追加
# ユーザ認証
user = _get_user(request)
# ↑追加
# オブジェクトの取得
movie = get_object_or_404(
Movie.objects.prefetch_related('movie_genres__genre'),
pk=movie_id,
)
# ↓追加
rating_map = {}
if user:
rating_map = {
rating.movie_id: rating for rating in UserMovieRating.objects.filter(user=user)
}
# ↑追加
# レスポンス
data = {
'movie': MovieMapper(
movie, # <- 「,」を追加
rating=rating_map.get(movie.movie_id), # <- 追加
).as_dict() if movie else None,
}
return Response(data, status.HTTP_200_OK)
...(略)...
実行確認
サインインビューの作成の手順にしたがってサインインし、アクセストークンを取得してください。取得したトークンを用いて、バックエンドサーバが起動している状態で、下記コマンドを実行してください。
$
curl -X GET http://localhost:8000/api/online/movies/1/ \
-H "Content-Type: application/json" \
-H "Authorization: Bearer <ACCESS_TOKEN>"
ユーザによる評価値が付与された映画データが取得できます。
下記コマンドを実行してください。
$
curl -X GET http://localhost:8000/api/online/movies/ \
-H "Content-Type: application/json" \
-H "Authorization: Bearer <ACCESS_TOKEN>"
ユーザによる評価値が付与された映画リストが取得できます。確認しやすいように、映画リストでランダムに取得している箇所を一時的に下記のように修正しても良いです。
src/backend/api/online/views.py
...(略)...
class MoviesView(APIView):
...(略)...
def get(self, request, format=None):
...(略)...
# オブジェクトの取得
# movies = Movie.objects.order_by('?')[:20]\
# .prefetch_related('movie_genres__genre')
movies = Movie.objects.all()[:20]\
.prefetch_related('movie_genres__genre')
...(略)...
フロントエンド
API
src/frontend/src/api/movies/getMovies.ts
...(略)...
/**
* 映画リスト取得API
* @returns movies - 映画リスト
*/
const getMovies = async (): Promise<{ movies: Movie[] }> => {
const access = typeof window !== 'undefined' ? localStorage.getItem('access') : null; // <- 追加
const url = `${context.apiRootUrl?.replace(/\/$/g, '')}/online/movies/`;
const headers: Record<string, string> = {
Accept: 'application/json',
'Content-Type': 'application/json',
...(access ? { Authorization: `Bearer ${access}` } : {}), // <- 追加
};
return await fetcher(url, {
method: 'GET',
headers: headers,
cache: 'no-store',
});
};
export default getMovies;
src/frontend/src/api/movies/getMovie.ts
...(略)...
/**
* 映画取得API
* @param movieId - 映画ID
* @returns movie - 映画オブジェクト
*/
const getMovie = async (movieId: number): Promise<{ movie: Movie }> => {
const access = typeof window !== 'undefined' ? localStorage.getItem('access') : null; // <- 追加
const url = `${context.apiRootUrl?.replace(/\/$/g, '')}/online/movies/${movieId}`;
const headers: Record<string, string> = {
Accept: 'application/json',
'Content-Type': 'application/json',
...(access ? { Authorization: `Bearer ${access}` } : {}), // <- 追加
};
return await fetcher(url, {
method: 'GET',
headers: headers,
cache: 'no-store',
});
};
export default getMovie;
ブラウザで下記それぞれの URL にアクセスしてください。
評価値を入力した後、ブラウザを更新してください。入力した評価値が維持されています。