from flask import Blueprint, render_template, request, redirect, url_for, flash, session from models import Movie, Genre, Rating, UserDefault, Occupation, User # 导入所需的模型 from sqlalchemy import func from helpers import get_recommendations # 创建一个蓝图 movies_bp = Blueprint('movies', __name__) # 电影详情路由 @movies_bp.route('/detail') def detail(): # 检查用户是否登录 if 'user_id' not in session: flash("Please log in to access this page.") return redirect(url_for('auth')) # 获取电影 ID 参数 movie_id = request.args.get('id') if not movie_id: return redirect(url_for('dashboard')) # 查询电影详情 movie = Movie.query.filter_by(id=movie_id).first() if not movie: return redirect(url_for('dashboard')) # 解析 genres 字段,查询对应的 genre 名称 genre_ids = movie.genres.split(",") if movie.genres else [] genres = Genre.query.filter(Genre.id.in_(genre_ids)).all() genre_names = [genre.name for genre in genres] # 获取评分分布 rating_counts = ( Rating.query.with_entities(Rating.rating, func.count(Rating.rating).label('count')) .filter_by(item_id=movie_id) .group_by(Rating.rating) .all() ) total_ratings = sum(count for _, count in rating_counts) rating_distribution = {i: 0 for i in range(1, 6)} # 初始化 1-5 分的评分比例为 0 for rating, count in rating_counts: rating_distribution[rating] = count / total_ratings if total_ratings else 0 # 获取当前用户类型 user_id = session.get('user_id') user = User.query.filter_by(id=user_id).first() user_type = user.user_type if user else 'U' # 默认为普通用户 # 如果是制片人用户,进行用户喜好详细分析 user_analysis = None if user_type == 'P': # 性别分析 gender_stats = ( Rating.query.join(UserDefault, Rating.user_id == UserDefault.user_id) .filter(Rating.item_id == movie_id) .with_entities(UserDefault.gender, func.avg(Rating.rating).label('average'), func.count(Rating.rating).label('count')) .group_by(UserDefault.gender) .all() ) gender_analysis = {gender: {'average': avg, 'count': cnt} for gender, avg, cnt in gender_stats} # 年龄分析 age_ranges = [ (0, 10), (11, 20), (21, 30), (31, 40), (41, 50), (51, 60), (61, 70), (71, 80) ] age_analysis = {} for min_age, max_age in age_ranges: age_data = ( Rating.query.join(UserDefault, Rating.user_id == UserDefault.user_id) .filter(Rating.item_id == movie_id, UserDefault.age.between(min_age, max_age)) .with_entities(func.avg(Rating.rating).label('average'), func.count(Rating.rating).label('count')) .first() ) age_analysis[f"{min_age}-{max_age}"] = { 'average': age_data.average if age_data and age_data.count else 0, 'count': age_data.count if age_data else 0 } # 职业分析 occupation_stats = ( Rating.query.join(UserDefault, Rating.user_id == UserDefault.user_id) .filter(Rating.item_id == movie_id) .with_entities(UserDefault.occupation, func.avg(Rating.rating).label('average'), func.count(Rating.rating).label('count')) .group_by(UserDefault.occupation) .all() ) occupation_analysis = {} for occ_id, avg, cnt in occupation_stats: occupation_name = Occupation.query.filter_by(id=occ_id).first().name occupation_analysis[occupation_name] = {'average': avg, 'count': cnt} user_analysis = { 'gender_analysis': gender_analysis, 'age_analysis': age_analysis, 'occupation_analysis': occupation_analysis } # 获取相似电影并转换每部相似电影的 genres 为名称 similar_movie_ids = [int(mid) for mid in movie.similar_movie.split(',')] if movie.similar_movie else [] similar_movies = Movie.query.filter(Movie.id.in_(similar_movie_ids)).all() similar_movies_data = [] for sim_movie in similar_movies: sim_genre_ids = sim_movie.genres.split(",") if sim_movie.genres else [] sim_genres = Genre.query.filter(Genre.id.in_(sim_genre_ids)).all() sim_genre_names = [genre.name for genre in sim_genres] similar_movies_data.append({ 'id': sim_movie.id, 'title': sim_movie.title, 'release_date': sim_movie.release_date, 'genres': ", ".join(sim_genre_names), # 转换后的 genres 名称 'rating_count': sim_movie.rating_count, 'average_rating': sim_movie.average_rating, 'actor': sim_movie.actor, }) # 获取“猜你喜欢”的推荐数据 recommendations_data = get_recommendations(user_id, page=1, per_page=10) if user_id else {} # 渲染电影详情模板 return render_template( 'detail.html', movie=movie, genre_names=genre_names, rating_distribution=rating_distribution, user_analysis=user_analysis, user_type=user_type, **recommendations_data, similar_movies=similar_movies_data, # 使用转换后的相似电影数据 )