Django项目中Chart.js无法渲染:Uncaught ReferenceError: Chart未定义
Django集成Chart.js报错"Chart is not defined"的解决方案
问题描述
我在Django项目中集成Chart.js,先尝试使用官网示例图表,但默认图表无法渲染,持续报错:Uncaught ReferenceError: Chart is not defined。我认为是库未正确安装,但已尝试多个CDN仍无法解决。
相关代码
HTML模板(health_hub_tracker.html)
{% extends 'base.html' %} {% load static %} {% block content %} <canvas id="myChart" width="400" height="400"></canvas> <script> const ctx = document.getElementById('myChart').getContext('2d'); const myChart = new Chart(ctx, { type: 'bar', data: { labels: ['Weight', 'Run Distance', 'Run Time', 'Date'], datasets: [{ label: '# of Votes', data: [12, 19, 3, 5, 2, 3], backgroundColor: [ 'rgba(255, 99, 132, 0.2)', 'rgba(54, 162, 235, 0.2)', 'rgba(255, 206, 86, 0.2)', 'rgba(75, 192, 192, 0.2)', 'rgba(153, 102, 255, 0.2)', 'rgba(255, 159, 64, 0.2)' ], borderColor: [ 'rgba(255, 99, 132, 1)', 'rgba(54, 162, 235, 1)', 'rgba(255, 206, 86, 1)', 'rgba(75, 192, 192, 1)', 'rgba(153, 102, 255, 1)', 'rgba(255, 159, 64, 1)' ], borderWidth: 1 }] }, options: { scales: { y: { beginAtZero: true } } } }); </script> {% endblock content %}
views.py
def health_hub_tracker(request): serialized_stats = [] for stats in HealthStats.objects.filter(user=request.user): serialized_stats.append({ "weight": stats.weight, "run_distance": stats.run_distance, "run_time": stats.run_time, "date": stats.date, }) context = { "stats": serialized_stats } print(serialized_stats) return render(request, "health_hub_tracker.html", context)
base.html
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> {% load static %} <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@5.2.0/dist/css/bootstrap.min.css" integrity="sha384-gH2yIJqKdNHPEq0n4Mqa/HGKIhSkIHeL5AyhkYV8i59U5AR6csBvApHHNl/vI1Bx" crossorigin="anonymous"> <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@fortawesome/fontawesome-free@6.1.2/css/fontawesome.min.css"> <!-- Google Fonts --> <link rel="preconnect" href="https://fonts.googleapis.com"> <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin> <link href="https://fonts.googleapis.com/css2?family=Lato:wght@300&family=Oswald&display=swap" rel="stylesheet"> <!-- FavIcon --> <link rel="icon" href="{% static 'favicon.ico' %}"> <title>Your Health Now</title> </head> <body> <!-- Title --> <div class="container-fluid p-3 bg-primary text-white text-center"> <div class="row text-center"> <div class="col-sm-12"> <h1 class="display-1">Your Health Now</h1> </div> <!-- Navbar with burger menu --> <div class="sm-12 text-center"> <nav class="navbar navbar-expand-lg navbar-dark bg-blue"> <div class="container-fluid"> <button class="navbar-toggler ms-auto" type="button" data-bs-toggle="collapse" data-bs-target="#n_bar" aria-controls="navbarNavAltMarkup" aria-label="Toggle navigation"> <span class="navbar-toggler-icon ms-auto"></span> </button> <div class="collapse navbar-collapse" id="n_bar"> <ul class="nav navbar-nav ms-auto"> <li class="nav-item"><a class="nav-link text-white" href="{% url 'HealthHub:home' %}"><strong>Home</strong></a></li> {% if user.is_authenticated %} <li class="nav-item"><a class="nav-link text-white" href="{% url 'HealthHub:health_hub' %}"><strong>My Health</strong></a></li> <li class="nav-item"><a class="nav-link text-white" href="{% url 'account_logout' %}"><strong>Logout</strong></a></li> {% else %} <li class="nav-item"><a class="nav-link text-white" href="{% url 'account_login' %}"><strong>Login</strong></a></li> {% endif %} <li class="nav-item"><a class="nav-link text-white" href="{% url 'account_signup' %}"><strong>Signup</strong></a></li> </ul> </div> </div> </nav> </div> </div> </div> <!-- Main Content --> <div class="container-fluid text-center"> <div class="row justify-content-center"> <div class="col-sm-8"> {% block content %} {% endblock content %} </div> </div> </div> <!-- Footer --> <footer class="container-fluid fixed-bottom bg-secondary"> <a href="#" class="btn btn-secondary float-end">Back to top</a> <a href="https://github.com/BenD2525" target="_blank" rel="noopener" aria-label="GitHub" class="text-white">Ben Dawson<i class="fa-brands fa-github" aria-hidden="true"></i></a> </footer> <!-- Popper JS --> <script src="https://cdn.jsdelivr.net/npm/@popperjs/core@2.10.2/dist/umd/popper.min.js" integrity="sha384-7+zCNj/IqJ95wo16oMtfsKbZ9ccEh31eOz1HGyDuCQ6wgnyJNSYdrPa03rtR1zdB" crossorigin="anonymous"> </script> <!-- Bootstrap --> <script src="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/js/bootstrap.min.js" integrity="sha384-QJHtvGhmr9XOIpI6YVutG+2QOK9T+ZnN4kzFN1RtK3zEFEIsxhlmWl5/YESvpZ13" crossorigin="anonymous"> </script> <!-- Font Awesome --> <script src="https://kit.fontawesome.com/cdefc89d16.js" crossorigin="anonymous"></script> <!-- JQuery --> <script src="https://code.jquery.com/jquery-3.6.1.min.js" integrity="sha256-o88AwQnZB+VDvE9tvIXrMQaPlFFSUTR+nldQm1LuPXQ=" crossorigin="anonymous"></script> <!-- Chart.js --> <script src="https://cdn.jsdelivr.net/npm/chart.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/3.9.1/chart.min.js" integrity="sha512-ElRFoEQdI5Ht6kZvyzXhYG9NqjtkmlkfYk0wr6wHxU9JEHakS7UJZNeml5ALk+8IKlU6jDgMabC3vkumRokgJA==" crossorigin="anonymous" referrerpolicy="no-referrer"></script> </body> </html>
问题原因及解决方案
核心原因
模板中的Chart初始化脚本执行时,Chart.js库还未加载完成。base.html里的Chart.js脚本放在页面底部,而模板content块里的脚本在页面中间,先于Chart.js加载执行,导致找不到Chart对象。另外重复加载两个版本的Chart.js,可能引发冲突。
修复步骤
移除重复的Chart.js CDN
在base.html中删除其中一个Chart.js脚本,保留一个稳定版本,比如只保留带版本号的:<!-- Chart.js --> <script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/3.9.1/chart.min.js" integrity="sha512-ElRFoEQdI5Ht6kZvyzXhYG9NqjtkmlkfYk0wr6wHxU9JEHakS7UJZNeml5ALk+8IKlU6jDgMabC3vkumRokgJA==" crossorigin="anonymous" referrerpolicy="no-referrer"></script>确保初始化脚本在Chart.js之后执行
两种可选方式:方式一:新增脚本block
在base.html的Chart.js脚本之后添加自定义脚本block:<!-- Chart.js --> <script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/3.9.1/chart.min.js" integrity="sha512-ElRFoEQdI5Ht6kZvyzXhYG9NqjtkmlkfYk0wr6wHxU9JEHakS7UJZNeml5ALk+8IKlU6jDgMabC3vkumRokgJA==" crossorigin="anonymous" referrerpolicy="no-referrer"></script> {% block extra_js %}{% endblock extra_js %}修改模板,将初始化脚本移到新block中:
{% extends 'base.html' %} {% load static %} {% block content %} <canvas id="myChart" width="400" height="400"></canvas> {% endblock content %} {% block extra_js %} <script> const ctx = document.getElementById('myChart').getContext('2d'); const myChart = new Chart(ctx, { // 图表配置和数据... }); </script> {% endblock extra_js %}方式二:监听DOM加载完成
直接修改模板中的脚本,确保DOM和脚本都加载完成后再执行:<script> document.addEventListener('DOMContentLoaded', function() { const ctx = document.getElementById('myChart').getContext('2d'); const myChart = new Chart(ctx, { // 图表配置和数据... }); }); </script>
内容的提问来源于stack exchange,提问作者BenD2525
相关产品推荐
相关产品推荐

