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

Django点击按钮更新Notification模型viewed_at空值为当前时间问题排查

代码存在的问题及修复方案

核心错误点

  • 路由参数缺失:你定义的viewed-notification路由要求传入notification_id参数,但模板中调用{% url 'users:viewed-notification' %}时没有传递该参数,会直接触发路由匹配错误,请求根本无法到达mark_as_read视图。
  • 请求类型与取值不匹配:你用<a>标签发起的是GET请求,但mark_as_read视图中从request.POST取next参数,GET请求不存在POST数据,会触发KeyError导致视图报错。
  • HTML语法错误:模板中的<tr>、<td>、<a>、<span>标签均存在嵌套错误、未正确闭合的问题,会导致浏览器渲染异常,链接可能无法正常触发。
  • 时区与安全、异常处理缺陷:直接使用datetime.datetime.now()赋值,若项目开启了时区配置(USE_TZ = True)会导致时间存储错误;同时直接用get()查询通知,传入不存在的ID会直接抛出500错误,也没有校验当前用户是否为通知所属人,存在越权操作的安全漏洞。

修正后的代码

1. 模板部分

<table class="table table-theme-3 text-left">
  <tbody>
    {% for item in unviewed_list %}
    <tr>
      <td>{{ item.message }}</td>
      <td>{{ item.created_at}}</td>
      <td>
        <span class="badge badge-error">
          <a class="button button--success button--sm" href="{% url 'users:viewed-notification' item.id %}?next={{ request.path }}">
            See it
          </a>
        </span>
      </td>
    </tr>
    {% endfor %}
  </tbody>
</table>

2. mark_as_read视图部分

from django.shortcuts import get_object_or_404, redirect
from django.utils import timezone

def mark_as_read(request, notification_id):
    # 同时校验权限、防止查询不存在的通知
    notification = get_object_or_404(Notification, pk=notification_id, user=request.user)
    notification.viewed_at = timezone.now()
    notification.save()
    # 优先取GET参数的next,默认跳转回通知列表页
    next_url = request.GET.get('next', '/notifications/')
    return redirect(next_url)

3. 可选性能优化

可以把更新操作改成单句SQL执行,减少数据库请求次数:

Notification.objects.filter(pk=notification_id, user=request.user).update(viewed_at=timezone.now())

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.11 06:36:01