如何在Django中通过带资源ID的URL展示查询结果并生成D3.js图表
Hey there! Let's work through this together—you've already knocked out the tough parts (importing your data, setting up the Django app and model), so we just need to tie the URL routing, data fetching, and D3.js visualization together. Here's a step-by-step fix:
First, let's sort out the URL routing—this is likely where you hit a snag. You'll need to set up both project-level and app-level URLs:
Project urls.py (root directory)
Make sure you include your dashboard app's URLs so Django knows where to route requests:
from django.contrib import admin from django.urls import path, include urlpatterns = [ path('admin/', admin.site.urls), path('', include('dashboard.urls')), # Routes all non-admin requests to dashboard's URLs ]
Dashboard App urls.py
Add a path that captures the resource_id and maps it to a view function:
from django.urls import path from . import views urlpatterns = [ # Add this line to handle resource detail requests path('resource/<int:resource_id>/', views.resource_detail, name='resource-detail'), ]
The <int:resource_id> part tells Django to capture an integer value from the URL and pass it to your view as a parameter.
Next, create a view function that grabs the specific Resource object and prepares data for D3.js. We'll use get_object_or_404 to handle cases where the resource ID doesn't exist:
# dashboard/views.py from django.shortcuts import render, get_object_or_404 from .models import Resource import json # To convert Python data to JSON for D3 def resource_detail(request, resource_id): # Fetch the specific resource, or return a 404 if it doesn't exist resource = get_object_or_404(Resource, id=resource_id) # Prepare data in a format D3 can use—customize this to match your Resource model fields d3_ready_data = { "resource_id": resource.id, "resource_name": resource.name, # Replace with your actual field names "key_metrics": [ {"name": "Metric A", "value": resource.metric_a}, {"name": "Metric B", "value": resource.metric_b}, {"name": "Metric C", "value": resource.metric_c} ] } # Convert the Python dict to JSON so it's usable in JavaScript d3_data_json = json.dumps(d3_ready_data) # Pass both the raw resource object and JSON data to the template return render(request, 'dashboard/resource_detail.html', { 'resource': resource, 'd3_data': d3_data_json })
Now make a template that displays the resource details and renders a D3.js chart. First, set up your static files folder (if you haven't already) to host D3.js:
- Create
dashboard/static/dashboard/js/and download the latest D3.js file into this folder (e.g.,d3.v7.min.js). - Add
{% load static %}at the top of your template to access static files.
Here's a complete template example:
<!-- dashboard/templates/dashboard/resource_detail.html --> {% load static %} <!DOCTYPE html> <html> <head> <title>Resource {{ resource.id }}</title> <script src="{% static 'dashboard/js/d3.v7.min.js' %}"></script> <style> .chart-container { width: 800px; height: 400px; margin: 30px auto; } .resource-details { max-width: 800px; margin: 0 auto; padding: 20px; } </style> </head> <body> <div class="resource-details"> <h1>Resource #{{ resource.id }}: {{ resource.name }}</h1> <p>Description: {{ resource.description }}</p> <!-- Replace with your model fields --> <!-- Add any other resource details you want to display --> </div> <div class="chart-container" id="resource-chart"></div> <script> // Parse the JSON data from Django into a JavaScript object const resourceData = JSON.parse('{{ d3_data|safe }}'); // D3.js Bar Chart Example (customize this to match your data/chart type) const width = 800; const height = 400; const margin = { top: 20, right: 20, bottom: 40, left: 50 }; // Create SVG container const svg = d3.select("#resource-chart") .append("svg") .attr("width", width) .attr("height", height); // Set up scales const xScale = d3.scaleBand() .domain(resourceData.key_metrics.map(metric => metric.name)) .range([margin.left, width - margin.right]) .padding(0.1); const yScale = d3.scaleLinear() .domain([0, d3.max(resourceData.key_metrics, d => d.value)]) .range([height - margin.bottom, margin.top]); // Add X axis svg.append("g") .attr("transform", `translate(0, ${height - margin.bottom})`) .call(d3.axisBottom(xScale)) .selectAll("text") .attr("font-size", "12px"); // Add Y axis svg.append("g") .attr("transform", `translate(${margin.left}, 0)`) .call(d3.axisLeft(yScale)) .attr("font-size", "12px"); // Add bars svg.selectAll(".bar") .data(resourceData.key_metrics) .enter() .append("rect") .attr("class", "bar") .attr("x", d => xScale(d.name)) .attr("y", d => yScale(d.value)) .attr("width", xScale.bandwidth()) .attr("height", d => height - margin.bottom - yScale(d.value)) .attr("fill", "#3498db") .on("mouseover", function() { d3.select(this).attr("fill", "#2980b9"); }) .on("mouseout", function() { d3.select(this).attr("fill", "#3498db"); }); </script> </body> </html>
Run your Django server with python manage.py runserver, then visit http://localhost:8000/resource/1 (replace 1 with a valid resource ID from your database). You should see the resource details and a working D3.js chart!
内容的提问来源于stack exchange,提问作者Sander de Ruiter

