You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Django实现带评论影视按评分降序展示及FieldError修复

问题解答

一、修复FieldError错误

错误原因

  1. index视图中sort_by = request.POST.get('sort_by',''),当未获取到sort_by参数时,sort_by为空字符串,传给order_by()会导致Django无法解析空字段名,触发报错。
  2. movie.GET.get('id')和tv.GET.get('id')写法错误:movie和tv是QuerySet对象,没有GET属性,需从request.GET中获取请求参数。

修复后的index视图代码

def index(request):
    # 获取排序字段,默认按评分降序,同时限制合法字段避免错误
    sort_by = request.GET.get('sort_by', '-stars')
    allowed_sort_fields = ['id', 'stars', '-id', '-stars']
    if sort_by not in allowed_sort_fields:
        sort_by = '-stars'
    
    # 按合法字段排序
    movies = Movie.objects.order_by(sort_by)
    tvs = TV.objects.order_by(sort_by)
    
    # 正确从request.GET获取id参数
    movie_id = request.GET.get('id')
    tv_id = request.GET.get('id')
    print(tv_id)
    
    # 可选:过滤评分低于指定阈值的内容(示例阈值3.0)
    threshold = request.GET.get('threshold', 3.0)
    try:
        threshold = float(threshold)
        movies = movies.filter(stars__gte=threshold)
        tvs = tvs.filter(stars__gte=threshold)
    except ValueError:
        # 阈值非法时使用默认值过滤
        movies = movies.filter(stars__gte=3.0)
        tvs = tvs.filter(stars__gte=3.0)
    
    context = {
        'movies': movies,
        'tvs': tvs
    }
    return render(request, 'Movie/index.html', context)

二、实现选择「score」选项时按评分降序展示

需要前端交互与后端接口配合完成:

1. 前端修改(HTML+JS)

HTML调整选项文本

{% extends "base.html" %}
{% block content %}
    <h2>Trending</h2>
    <div class="input-group mb-3">
        <select class="form-select" id="media_type">
          <option selected>All Trending Media Types</option>
          <option value="movie">All Trending Movies(day)</option>
          <option value="tv">All Trending TV Shows(day)</option>
          <option value="person">All Trending Persons(day)</option>
          <option value="score">按评分降序展示</option>
        </select>
    </div>
    
    <div id="trendings" class="row">

    </div>
    {% load static %}
    <script src="{% static 'js/Movieindex.js' %}"></script>
    
{% endblock %}

JS修改交互逻辑,新增评分排序请求

fetchTrendingResults("all", "week")

var mediaType = document.getElementById("media_type")
mediaType.addEventListener("change", function(event) {
    const selectedValue = mediaType.options[mediaType.selectedIndex].value
    if (selectedValue === 'score') {
        fetchSortedByScore()
    } else {
        fetchTrendingResults(selectedValue, "day")
    }
})

function fetchTrendingResults(media_type, time_window) {
    var trendingDiv = document.getElementById("trendings")
    trendingDiv.innerHTML = ""

    fetch(`/api/trendings?media_type=${media_type}&time_window=${time_window}`, {
        method: "GET",
        headers: {
            "Content-Type": "application/json"
        }}
        )
    .then(res => res.json())
    .then(data => {
        renderMediaCards(data.results)
    })
}

function fetchSortedByScore() {
    var trendingDiv = document.getElementById("trendings")
    trendingDiv.innerHTML = ""

    fetch(`/api/sorted-by-score?threshold=3.0`, {
        method: "GET",
        headers: {
            "Content-Type": "application/json"
        }}
        )
    .then(res => res.json())
    .then(data => {
        renderMediaCards(data)
    })
}

// 提取公共渲染函数,避免重复代码
function renderMediaCards(items) {
    for (let i=0; i<items.length; i++) {
        var mainDiv = document.createElement("div");
        mainDiv.setAttribute("class", "card");
        mainDiv.setAttribute("style", "width: 18rem; margin: 0.5rem;");
        var img = document.createElement("img");
        img.setAttribute("src", "https://image.tmdb.org/t/p/w200" + items[i].poster_path);
        img.setAttribute("class", "card-img-top");
        img.setAttribute("alt", items[i].title || items[i].name);
        var body = document.createElement("div");
        body.setAttribute("class", "card-body");
        var title = document.createElement("h5");
        title.setAttribute("class", "card-title");
        title.innerHTML = items[i].name || items[i].title;
        // 显示评分
        var scoreText = document.createElement("p");
        scoreText.setAttribute("class", "card-text text-muted");
        scoreText.innerHTML = `评分: ${items[i].stars.toFixed(1)}`;
        var link = document.createElement("a");
        link.setAttribute("href", "/" + items[i].media_type + "/" + items[i].id + "/");
        link.setAttribute("class", "btn btn-primary");
        link.innerHTML = "查看详情";
        body.appendChild(title);
        body.appendChild(scoreText);
        body.appendChild(link);
        mainDiv.appendChild(img);
        mainDiv.appendChild(body);
        document.getElementById("trendings").appendChild(mainDiv);
    }
}

2. 后端新增评分排序API接口(views.py)

import requests
from django.http import JsonResponse
from .models import Movie, TV

TMDB_API_KEY = "你的TMDB API密钥"

def sorted_by_score(request):
    threshold = request.GET.get('threshold', 3.0)
    try:
        threshold = float(threshold)
    except ValueError:
        threshold = 3.0
    
    # 获取符合评分阈值的影视内容,按评分降序
    sorted_movies = Movie.objects.filter(stars__gte=threshold).order_by('-stars')
    sorted_tvs = TV.objects.filter(stars__gte=threshold).order_by('-stars')
    
    result = []
    
    # 补充电影的TMDB详情数据
    for movie in sorted_movies:
        tmdb_data = requests.get(f"https://api.themoviedb.org/3/movie/{movie.id}?api_key={TMDB_API_KEY}&language=en-US").json()
        result.append({
            'id': movie.id,
            'media_type': 'movie',
            'title': tmdb_data.get('title'),
            'poster_path': tmdb_data.get('poster_path'),
            'stars': movie.stars
        })
    
    # 补充剧集的TMDB详情数据
    for tv in sorted_tvs:
        tmdb_data = requests.get(f"https://api.themoviedb.org/3/tv/{tv.id}?api_key={TMDB_API_KEY}&language=en-US").json()
        result.append({
            'id': tv.id,
            'media_type': 'tv',
            'name': tmdb_data.get('name'),
            'poster_path': tmdb_data.get('poster_path'),
            'stars': tv.stars
        })
    
    # 合并后再次按评分降序,确保影视混排顺序正确
    result.sort(key=lambda x: x['stars'], reverse=True)
    
    return JsonResponse(result, safe=False)

3. 配置URL路由(urls.py)

在应用的urls.py中添加新接口路由:

from django.urls import path
from . import views

urlpatterns = [
    path('', views.index, name='index'),
    path('movie/<str:movie_id>/', views.view_movie_detail, name='view_movie_detail'),
    # 新增评分排序接口路由
    path('api/sorted-by-score/', views.sorted_by_score, name='sorted-by-score'),
    # 保留原有trendings接口路由
    path('api/trendings/', views.your_trendings_view, name='trendings'),
]

内容的提问来源于stack exchange,提问作者user19553515

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.25 23:33:30