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视图函数里,有两个核心错误:
- 获取到的Activity对象被赋值给了
id变量,既覆盖了URL传入的id参数,又和模板中需要的activity变量名不匹配 - 没有将获取到的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页面。修改步骤如下:
- 先在顶部导入该函数:
from django.shortcuts import render, redirect, get_object_or_404
- 调整视图函数:
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
相关产品推荐
相关产品推荐

