You need to enable JavaScript to run this app. Django项目部分用户访问鱼钩诱饵编辑页随机返回404错误求助
优惠活动
大模型
产品
解决方案
定价
更多

Django项目部分用户访问鱼钩诱饵编辑页随机返回404错误求助

根因说明

你使用的Django通用视图UpdateView默认会从URL参数中提取pk/slug字段,去查询对应模型(此处为HookBait)的单条记录,查询不到直接返回404。
但你当前URL路径中传入的pk是渔民IDfisherman_id,并非HookBait表的主键:只有当用户的渔民ID恰好和某条HookBait记录的主键值相等时才能正常访问,否则就会触发404,这就是部分用户报错、部分用户正常的核心原因。

排查方向

  • 取报错用户的渔民ID,直接在数据库中查询HookBait表是否存在主键等于该渔民ID的记录,没有的话直接访问对应链接必然404,可直接验证根因。
  • 查看服务端404访问日志,提取请求URL中的pk值,核对HookBait表主键确认是否存在对应记录。

解决方案

你的页面实际是编辑当前用户名下所有鱼钩诱饵的表单集,不需要用到UpdateView的单对象查询逻辑,推荐两种修复方案:

方案1:更换视图基类(更推荐)

直接继承FormView,去掉无用的单对象查询逻辑:

# views.py 修改示例
from django.views.generic import FormView
from django.shortcuts import redirect

class HookBaitUpdateView(FormView):
    template_name = "user_profile/hookbaits.html"

    def get_context_data(self, **kwargs):
        context = super().get_context_data(**kwargs)
        context['formset'] = HookBaitFormset(queryset=HookBait.objects.filter(fisherman=self.request.user.fisherman))
        return context

    def post(self, request, *args, **kwargs):
        formset = HookBaitFormset(request.POST)
        if formset.is_valid():
            instances = formset.save(commit=False)
            for instance in instances:
                instance.fisherman = self.request.user.fisherman
                instance.save()
            return redirect(reverse('user_profile:profile', args=(self.kwargs['pk'],)))
        return self.render_to_response(self.get_context_data(formset=formset))

方案2:保留UpdateView,重写默认查询逻辑

如果要保留UpdateView的继承关系,修改URL参数名避免冲突,同时重写get_object方法覆盖默认查询逻辑:

  1. 修改路由配置,将参数名改为fisherman_id避免和默认pk冲突:
# urls.py 修改示例
app_name = "user_profile"
urlpatterns = [
    path("profile/<int:pk>/", views.ProfileView.as_view(), name="profile"),
    path("profile/<int:fisherman_id>/hookbaits/", views.HookBaitUpdateView.as_view(), name="hookbaits"),
]
  1. 重写视图的get_object方法:
# views.py 新增get_object方法
class HookBaitUpdateView(UpdateView):
    model = HookBait
    template_name = "user_profile/hookbaits.html"
    form_class = HookBaitForm

    def get_object(self, queryset=None):
        # 按实际业务需要返回对象,此处示例返回当前用户的第一条鱼钩诱饵记录,无记录则返回空实例
        return HookBait.objects.filter(fisherman=self.request.user.fisherman).first() or HookBait(fisherman=self.request.user.fisherman)

    # 原有其他方法保持不变

额外优化建议

  • 增加权限校验逻辑,确保URL中传入的渔民ID和当前登录用户的渔民ID一致,避免用户修改URL访问他人数据。
  • 服务端404日志补充请求用户ID、请求URL字段,方便后续快速排查类似问题。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.10 01:03:00