用Django和Vue实现电影个性化推荐系统的完整实践

103 阅读4分钟

一、个人简介

  • 💖💖作者:计算机编程果茶熊
  • 💙💙个人简介:曾长期从事计算机专业培训教学,担任过编程老师,同时本人也热爱上课教学,擅长Java、微信小程序、Python、Golang、安卓Android等多个IT方向。会做一些项目定制化开发、代码讲解、答辩教学、文档编写、也懂一些降重方面的技巧。平常喜欢分享一些自己开发中遇到的问题的解决办法,也喜欢交流技术,大家有技术代码这一块的问题可以问我!
  • 💛💛想说的话:感谢大家的关注与支持!
  • 💕💕文末获取源码联系计算机编程果茶熊

二、前言

  • 电影个性化推荐系统是一款基于Java/Python双版本开发的综合性影视推荐平台,采用Spring Boot(Spring+SpringMVC+Mybatis)或Django作为后端框架,前端使用Vue+ElementUI+HTML技术栈,数据存储依托MySQL数据库,整体采用B/S架构设计。系统核心功能包括个性化电影推荐、用户中心管理、电影分类管理、热门电影展示与管理、详细电影信息维护等。用户可通过系统首页快速获取推荐内容,在个人中心管理自己的偏好设置和观影记录,通过交流论坛与其他影迷分享观影体验和评论。管理员可对电影类别、电影信息进行全面管理,包括添加、修改和删除操作。系统还提供电影资讯及其分类功能,用户可浏览最新电影动态、影评和行业新闻。首页轮播图管理功能使管理员能够灵活调整系统视觉呈现,系统简介模块则向用户展示平台理念和使用指南。整体而言,该系统通过技术与功能的有机结合,为用户提供了一站式、个性化的电影推荐与交流平台,满足不同用户的观影需求和社区互动体验。
  • 开发语言:Java+Python
  • 数据库:MySQL
  • 系统架构:B/S
  • 后端框架:SpringBoot(Spring+SpringMVC+Mybatis)+Django
  • 前端:Vue+HTML+CSS+JavaScript+jQuery

三、电影个性化推荐系统-视频解说

用Django和Vue实现电影个性化推荐系统的完整实践

四、电影个性化推荐系统-功能介绍

电影信息.png

个人信息.png

后台系统首页.png

可视化.png

热门电影.png

热门电影管理.png

热门电影推送.png

系统管理.png

用户管理.png

五、电影个性化推荐系统-代码展示

// 核心功能1: 电影个性化推荐算法实现 public List getPersonalizedRecommendations(Long userId, int limit) { // 获取用户观影历史 List watchHistory = userWatchHistoryRepository.findByUserId(userId);

// 获取用户评分数据
List<UserRating> userRatings = userRatingRepository.findByUserId(userId);

// 提取用户偏好特征
Map<String, Double> userPreferences = new HashMap<>();
for (UserRating rating : userRatings) {
    Movie movie = movieRepository.findById(rating.getMovieId()).orElse(null);
    if (movie != null) {
        // 根据评分权重增加类别偏好
        for (Category category : movie.getCategories()) {
            String categoryName = category.getName();
            userPreferences.put(categoryName, 
                userPreferences.getOrDefault(categoryName, 0.0) + rating.getRating() * 0.2);
        }
        
        // 考虑导演因素
        userPreferences.put("director:" + movie.getDirector(), 
            userPreferences.getOrDefault("director:" + movie.getDirector(), 0.0) + rating.getRating() * 0.1);
    }
}

// 获取候选电影列表(排除已观看)
Set<Long> watchedMovieIds = watchHistory.stream()
    .map(UserWatchHistory::getMovieId)
    .collect(Collectors.toSet());
List<Movie> candidateMovies = movieRepository.findByIdNotIn(watchedMovieIds);

// 计算每部电影与用户偏好的匹配度
Map<Movie, Double> movieScores = new HashMap<>();
for (Movie movie : candidateMovies) {
    double score = 0.0;
    
    // 类别匹配度
    for (Category category : movie.getCategories()) {
        score += userPreferences.getOrDefault(category.getName(), 0.0);
    }
    
    // 导演匹配度
    score += userPreferences.getOrDefault("director:" + movie.getDirector(), 0.0);
    
    // 考虑电影热度因素
    score += movie.getPopularityScore() * 0.3;
    
    movieScores.put(movie, score);
}

// 排序并返回推荐结果
return movieScores.entrySet().stream()
    .sorted(Map.Entry.<Movie, Double>comparingByValue().reversed())
    .limit(limit)
    .map(Map.Entry::getKey)
    .collect(Collectors.toList());

}

//核心功能2: 电影信息管理服务 @Transactional public MovieDTO updateMovieInfo(Long movieId, MovieDTO movieDTO) { // 查找现有电影记录 Movie existingMovie = movieRepository.findById(movieId) .orElseThrow(() -> new ResourceNotFoundException("电影不存在,ID: " + movieId));

// 更新基本信息
existingMovie.setTitle(movieDTO.getTitle());
existingMovie.setDirector(movieDTO.getDirector());
existingMovie.setReleaseDate(movieDTO.getReleaseDate());
existingMovie.setDuration(movieDTO.getDuration());
existingMovie.setDescription(movieDTO.getDescription());
existingMovie.setRating(movieDTO.getRating());
existingMovie.setCoverImage(movieDTO.getCoverImage());

// 处理电影演员关系
if (movieDTO.getActors() != null) {
    // 清除现有演员关联
    existingMovie.getActors().clear();
    
    // 添加新的演员关联
    for (ActorDTO actorDTO : movieDTO.getActors()) {
        Actor actor = null;
        if (actorDTO.getId() != null) {
            actor = actorRepository.findById(actorDTO.getId())
                .orElseGet(() -> {
                    Actor newActor = new Actor();
                    newActor.setName(actorDTO.getName());
                    return actorRepository.save(newActor);
                });
        } else {
            actor = actorRepository.findByName(actorDTO.getName())
                .orElseGet(() -> {
                    Actor newActor = new Actor();
                    newActor.setName(actorDTO.getName());
                    return actorRepository.save(newActor);
                });
        }
        existingMovie.getActors().add(actor);
    }
}

// 处理电影类别关系
if (movieDTO.getCategories() != null) {
    existingMovie.getCategories().clear();
    
    for (CategoryDTO categoryDTO : movieDTO.getCategories()) {
        Category category = categoryRepository.findById(categoryDTO.getId())
            .orElseThrow(() -> new ResourceNotFoundException("类别不存在,ID: " + categoryDTO.getId()));
        existingMovie.getCategories().add(category);
    }
}

// 更新电影资源链接
if (movieDTO.getResourceLinks() != null) {
    // 删除旧的资源链接
    resourceLinkRepository.deleteByMovieId(movieId);
    
    // 添加新的资源链接
    for (ResourceLinkDTO linkDTO : movieDTO.getResourceLinks()) {
        ResourceLink link = new ResourceLink();
        link.setMovie(existingMovie);
        link.setUrl(linkDTO.getUrl());
        link.setType(linkDTO.getType());
        link.setQuality(linkDTO.getQuality());
        resourceLinkRepository.save(link);
    }
}

// 保存更新后的电影信息
Movie updatedMovie = movieRepository.save(existingMovie);

// 更新电影搜索索引
searchIndexService.updateMovieIndex(updatedMovie);

// 转换为DTO并返回
return movieMapper.toDTO(updatedMovie);

}

// 核心功能3: 交流论坛帖子管理

@Transactional public ForumPostDTO createForumPost(ForumPostCreateRequest request, Long userId) { // 验证用户是否存在 User user = userRepository.findById(userId) .orElseThrow(() -> new ResourceNotFoundException("用户不存在,ID: " + userId));

// 检查用户是否被禁言
if (user.getIsBanned()) {
    throw new UserBannedException("您的账号已被禁言,无法发布帖子");
}

// 检查内容是否违规
ContentCheckResult checkResult = contentModerationService.checkContent(request.getContent());
if (!checkResult.isApproved()) {
    throw new ContentViolationException("帖子内容包含违规信息: " + checkResult.getReason());
}

// 创建新帖子
ForumPost post = new ForumPost();
post.setTitle(request.getTitle());
post.setContent(request.getContent());
post.setUser(user);
post.setCreatedAt(LocalDateTime.now());
post.setUpdatedAt(LocalDateTime.now());
post.setViewCount(0);
post.setLikeCount(0);

// 处理帖子分类
if (request.getCategoryId() != null) {
    ForumCategory category = forumCategoryRepository.findById(request.getCategoryId())
        .orElseThrow(() -> new ResourceNotFoundException("论坛分类不存在,ID: " + request.getCategoryId()));
    post.setCategory(category);
    
    // 更新分类的帖子计数
    category.setPostCount(category.getPostCount() + 1);
    forumCategoryRepository.save(category);
}

// 处理帖子标签
if (request.getTags() != null && !request.getTags().isEmpty()) {
    Set<ForumTag> tags = new HashSet<>();
    for (String tagName : request.getTags()) {
        ForumTag tag = forumTagRepository.findByName(tagName)
            .orElseGet(() -> {
                ForumTag newTag = new ForumTag();
                newTag.setName(tagName);
                return forumTagRepository.save(newTag);
            });
        tags.add(tag);
    }
    post.setTags(tags);
}

// 处理关联电影
if (request.getRelatedMovieId() != null) {
    Movie relatedMovie = movieRepository.findById(request.getRelatedMovieId())
        .orElseThrow(() -> new ResourceNotFoundException("电影不存在,ID: " + request.getRelatedMovieId()));
    post.setRelatedMovie(relatedMovie);
    
    // 更新电影的讨论度
    relatedMovie.setDiscussionCount(relatedMovie.getDiscussionCount() + 1);
    movieRepository.save(relatedMovie);
}

// 处理附加图片
if (request.getAttachedImages() != null && !request.getAttachedImages().isEmpty()) {
    List<ForumPostImage> images = new ArrayList<>();
    for (String imageUrl : request.getAttachedImages()) {
        ForumPostImage image = new ForumPostImage();
        image.setPost(post);
        image.setImageUrl(imageUrl);
        images.add(image);
    }
    post.setImages(images);
}

// 保存帖子
ForumPost savedPost = forumPostRepository.save(post);

// 更新用户的发帖统计
user.setPostCount(user.getPostCount() + 1);
userRepository.save(user);

// 发送新帖子通知给关注该用户的粉丝
notificationService.sendNewPostNotification(savedPost);

// 转换为DTO并返回
return forumPostMapper.toDTO(savedPost);

}

六、电影个性化推荐系统-文档展示

lunwen.png

七、END

谢谢.png

💕💕文末获取源码联系计算机编程果茶熊