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

Django问题排查:URL传ID获取数据库数据并展示到独立页面

问题

我正在Web开发课程中使用Django开发一款活动追踪器,想要实现通过URL传递Activity的ID,在独立页面展示对应数据库对象的详情(类似网站的新闻详情页)。目前页面能正常加载且URL已带上对应ID,但页面无任何数据显示,我认为问题出在views.py中。以下是我的相关代码,希望得到正确从数据库获取数据并传递到HTML页面的方法,且不能使用课程未提及的额外库:

views.py

from django.shortcuts import render, redirect
from django.http import HttpResponse, HttpRequest
from . models import Activity

# Create your views here.
def index(request: HttpRequest):
    activites = Activity.objects.all()
    return render(request, "activity/index.html", {"activites" : activites})

def new_activity(request: HttpRequest):
        if request.method == 'POST':
            params = request.POST
            activity = Activity(
                activity_name = params.get("activity_name")

            )
            activity.save()
            return redirect("/")
        return render(request, "activity/new_activity.html")

def activity(request: HttpRequest, id):
     id = Activity.objects.get(id=id)
     return render(request, "activity/activity.html")

activity.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <h1>{{ activity.activity_name }}</h1>

</body>
</html>

models.py

from django.db import models
from datetime import timedelta

# Create your models here.
class Activity(models.Model):
    id = models.BigAutoField(primary_key=True)
    activity_name = models.TextField()

    def time_spent(self):
        delta = timedelta()
        for timelog in self.timelog_set.all():
            delta += (timelog.end_time - timelog.start_time)
        return str(delta)

class TimeLog(models.Model):
    id = models.BigAutoField(primary_key=True)
    start_time = models.TimeField()
    end_time = models.TimeField()
    activity = models.ForeignKey("Activity", related_name="time_logs", on_delete=models.CASCADE)

urls.py

from django.urls import path
from . import views

urlpatterns = [
    path("", views.index, name="index"),
    path("new_activity/", views.new_activity, name="new_activity"),
    path("activity/<int:id>", views.activity, name="activity")
]

我尝试过传递不同参数和名称,但都没有效果。

解决方案

你的问题出在views.py的activity视图函数里,有两个核心错误:

  1. 获取到的Activity对象被赋值给了id变量,既覆盖了URL传入的id参数,又和模板中需要的activity变量名不匹配
  2. 没有将获取到的Activity对象传递给模板上下文

修改后的activity视图函数如下:

def activity(request: HttpRequest, id):
    # 将查询到的对象赋值给activity变量,避免和参数id冲突
    activity = Activity.objects.get(id=id)
    # 把activity对象传入模板上下文,供页面渲染使用
    return render(request, "activity/activity.html", {"activity": activity})

可选优化(处理无效ID)

如果需要处理用户输入不存在ID的情况(避免服务器报错),可以使用Django内置的get_object_or_404函数,它会在对象不存在时返回404页面。修改步骤如下:

  1. 先在顶部导入该函数:
from django.shortcuts import render, redirect, get_object_or_404
  1. 调整视图函数:
def activity(request: HttpRequest, id):
    activity = get_object_or_404(Activity, id=id)
    return render(request, "activity/activity.html", {"activity": activity})

这个函数属于Django基础模块,一般Web开发课程都会覆盖,如果你的课程还没讲到,可以暂时使用前面的基础版本。

完成修改后,模板中的{{ activity.activity_name }}就能正确渲染出对应活动的名称了。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.17 21:14:55