Django中如何从外部API提取指定数据并存入数据库表?
解决Django从TMDB API导入指定字段到数据库的问题
我来帮你搞定这个问题!你现在的核心问题是没正确处理API返回的数据结构——API返回的字典里,真正的电影列表在results数组里,而且字段名和你的模型不匹配,直接把整个API响应传给序列化器肯定存不了指定数据。下面是具体的修改方案:
1. 核心思路
- 从API返回的
data中提取results数组(这才是包含所有电影数据的部分) - 将每个电影对象的
id映射为模型的movieid,original_title映射为模型的title - 由于你的模型中
title字段max_length=10,需要截断过长的标题避免保存失败 - 使用序列化器的
many=True参数批量处理多个电影数据
2. 修改后的view.py代码
from django.http import JsonResponse from rest_framework import status from rest_framework.response import Response from rest_framework.views import APIView import requests import json from .models import GetList from .serializer import GetListSerializers class MovieImportView(APIView): # 替换成你实际的视图类名 def post(self, request): api_key = "API-KEY" response = requests.get('https://api.themoviedb.org/3/movie/popular?api_key={}'.format(api_key)) data = json.loads(response.text) # 提取API返回的电影列表 movies_results = data.get('results', []) # 转换字段名并处理标题长度 processed_movies = [] for movie in movies_results: # 截断标题到10字符以内,匹配模型的max_length限制 truncated_title = movie.get('original_title', '')[:10] processed_movies.append({ 'movieid': movie.get('id'), 'title': truncated_title }) # 用many=True告诉序列化器要处理多个对象 serializer = GetListSerializers(data=processed_movies, many=True) if serializer.is_valid(): serializer.save() return Response(serializer.data, status=status.HTTP_201_CREATED) return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
3. 可选优化:批量创建提升效率
如果导入的电影数量较多,使用Django的bulk_create可以减少数据库交互次数,提升效率(同时可以增加去重逻辑避免重复插入):
def post(self, request): api_key = "API-KEY" response = requests.get('https://api.themoviedb.org/3/movie/popular?api_key={}'.format(api_key)) data = json.loads(response.text) movies_results = data.get('results', []) movie_objects = [] existing_movie_ids = GetList.objects.values_list('movieid', flat=True) for movie in movies_results: movie_id = movie.get('id') # 跳过已存在的电影,避免重复 if movie_id not in existing_movie_ids: truncated_title = movie.get('original_title', '')[:10] movie_objects.append(GetList( movieid=movie_id, title=truncated_title )) # 批量创建所有新电影 GetList.objects.bulk_create(movie_objects) return Response({"message": f"成功导入{len(movie_objects)}部电影"}, status=status.HTTP_201_CREATED)
4. 关键注意点
- 字段映射:必须手动把API的
id转成模型的movieid,original_title转成title,序列化器才能正确识别 - 标题长度限制:你的模型中
title最大长度是10,一定要截断过长的标题,否则会触发验证错误 - 异常处理:可以考虑添加API请求失败的捕获逻辑(比如
requests.exceptions.RequestException),避免因为API请求出错导致视图崩溃
内容的提问来源于stack exchange,提问作者code_freak
相关产品推荐
相关产品推荐

