如何按星级排序影视内容并过滤低评分?解决Django赋值错误
问题与解决
需求
- 按星级降序排序电影和剧集,过滤掉评分低于指定阈值的内容
- 通过各自ID调用TMDB API获取数据并展示
报错信息
'module' object does not support item assignment
相关代码
Django 模型代码
class Movie(models.Model): id = models.CharField(primary_key=True, editable=False, validators=[alphanumeric],max_length = 9999) stars = models.FloatField( blank=False, null=False, default=0, validators=[MinValueValidator(0.0), MaxValueValidator(10.0)] ) def get_comments(self): return Comment_movie.objects.filter(movie_id=self.id) def average_stars(self): comments = self.get_comments() n_comments = comments.count() if n_comments: self.stars = sum([comment.stars for comment in comments]) / n_comments else: self.stars = 0 return self.stars class TV(models.Model): id = models.CharField(primary_key=True, editable=False, validators=[alphanumeric],max_length = 9999) stars = models.FloatField( blank=False, null=False, default=0, validators=[MinValueValidator(0.0), MaxValueValidator(10.0)] ) def get_comments(self): return Comment_tv.objects.filter(tv_id=self.id) def average_stars(self): comments = self.get_comments() n_comments = comments.count() if n_comments: self.stars = sum([comment.stars for comment in comments]) / n_comments else: self.stars = 0 return self.stars
Django 视图代码
def Score_by(request): movies = Movie.objects.order_by('-stars') movie_list= [] if movies.exists(): for obj in movies: data = requests.get(f"https://api.themoviedb.org/3/movie/{obj.id}?api_key={TMDB_API_KEY}&language=en-US") movie_list.append(data.json()) context["movie"] = movie_list tv = TV.objects.order_by('-stars') tv_list = [] if tv.exists(): for obj in tv: data = requests.get(f"https://api.themoviedb.org/3/tv/{obj.id}?api_key={TMDB_API_KEY}&language=en-US") tv_list.append(data.json()) context["tv"] = tv_list return render(request, 'Movie/score_by.html', context)
Django 模板代码
<div class="row"> {% for m in movie.results %} <div class="card" style="width: 18rem;"> <img src="https://image.tmdb.org/t/p/w200{{ m.poster_path }}" class="card-img-top" alt="..."> <div class="card-body"> {% if not m.name %} <h5 class="card-title">{{ m.title }}</h5> {% else %} <h5 class="card-title">{{ m.name }}</h5> {% endif %} <p class="card-text">{{ m.overview }}</p> <a href="/{{ type }}/{{ m.id }}/" class="btn btn-primary">View Details</a> </div> </div> {% endfor %} </div> <h1>TV Score_by</h1> <div class="row"> {% for m in tv.results %} <div class="card" style="width: 18rem;"> <img src="https://image.tmdb.org/t/p/w200{{ m.poster_path }}" class="card-img-top" alt="..."> <div class="card-body"> {% if not m.name %} <h5 class="card-title">{{ m.title }}</h5> {% else %} <h5 class="card-title">{{ m.name }}</h5> {% endif %} <p class="card-text">{{ m.overview }}</p> <a href="/{{ type }}/{{ m.id }}/" class="btn btn-primary">View Details</a> </div> </div> {% endfor %} </div>
错误原因及修复
1. 核心错误:context未初始化
视图里直接使用context["movie"],但context要么是未定义变量,要么是误导入了同名模块(比如from django.template import context),导致无法执行字典赋值操作。
修复: 在视图开头初始化context为字典:
def Score_by(request): context = {} # 新增初始化代码 # 后续原有代码保持不变
2. 模板遍历逻辑错误
视图中movie_list是直接存储单条电影JSON对象的列表,没有results键,模板里的movie.results需改为movie,同理tv.results改为tv。
修复模板代码:
<div class="row"> {% for m in movie %} <!-- 原有卡片内容不变 --> {% endfor %} </div> <h1>TV Score_by</h1> <div class="row"> {% for m in tv %} <!-- 原有卡片内容不变 --> {% endfor %} </div>
3. 补充分数阈值过滤功能
要实现过滤低于指定阈值的内容,可从请求参数获取阈值,再在查询时添加过滤条件:
修改视图查询代码:
def Score_by(request): context = {} # 从URL参数获取阈值,默认值设为0.0 threshold = float(request.GET.get('threshold', 0.0)) # 先过滤符合分数要求的内容,再按星级降序排序 movies = Movie.objects.filter(stars__gte=threshold).order_by('-stars') movie_list= [] if movies.exists(): for obj in movies: data = requests.get(f"https://api.themoviedb.org/3/movie/{obj.id}?api_key={TMDB_API_KEY}&language=en-US") movie_list.append(data.json()) context["movie"] = movie_list # TV部分同理添加过滤 tv = TV.objects.filter(stars__gte=threshold).order_by('-stars') tv_list = [] if tv.exists(): for obj in tv: data = requests.get(f"https://api.themoviedb.org/3/tv/{obj.id}?api_key={TMDB_API_KEY}&language=en-US") tv_list.append(data.json()) context["tv"] = tv_list return render(request, 'Movie/score_by.html', context)
4. 可选优化:减少重复API调用
每次请求都调用TMDB API会影响性能,可考虑将API返回的数据缓存到模型字段中,或使用Django缓存框架降低重复请求频率。
内容的提问来源于stack exchange,提问作者user19553515
相关产品推荐
相关产品推荐

