Django应用问题:User ID与Trader ID匹配却无法显示个人交易记录
Django股票交易记录应用:用户无法查看自己交易记录的问题解决
问题描述
开发基于Django的股票交易记录应用,采用Django默认User模型实现登录认证。Entry模型通过trader外键关联User,需求是登录用户仅能查看自己的交易记录。但登录后,尽管数据库中Entry的trader.id与当前User的ID完全匹配,页面却无法显示个人记录;将视图过滤代码改为Entry.objects.all()后能显示所有记录,说明数据存在,但过滤逻辑失效。
核心原因分析
- 创建Entry时未关联当前用户:EntryForm排除了
trader字段,EntryView的post方法中直接调用form.save()时,未手动设置trader关联当前登录用户,导致新创建的Entry无法正确绑定用户(若模型中trader设为null=False,此处本应抛出数据库完整性错误,推测数据可能是通过后台手动创建,或模型曾允许trader为null)。 - SingleEntryView字段名错误:编辑Entry时,代码错误使用
form.instance.user = request.user,但模型中关联用户的字段是trader而非user,导致编辑后的Entry关联关系异常。 - 过滤逻辑语法本身正确,但如果Entry的
trader字段未正确赋值,过滤自然无法返回匹配结果。
解决方案
1. 修复EntryView的post方法,保存时关联当前用户
修改views.py中EntryView的post方法,在表单验证通过后,先绑定当前用户到trader字段再保存:
def post(self, request): form = EntryForm(request.POST, request.FILES) if form.is_valid(): # 先关联当前用户到trader字段 entry = form.save(commit=False) entry.trader = request.user entry.save() messages.success(request, "Entry created!") return redirect("/") else: messages.error(request, "Please correct the errors below.") return render(request, "entries.html", {"form":form})
2. 修复SingleEntryView中的字段错误
修改SingleEntryView的post方法,将错误的user字段改为trader,同时添加权限验证:
def SingleEntryView(request, pk): entry = Entry.objects.get(pk=pk) # 验证当前用户是否有权限编辑该记录 if entry.trader != request.user: messages.error(request, "你没有权限编辑此记录") return redirect("/") if request.method == 'POST': form = EntryForm(request.POST, request.FILES, instance=entry) if form.is_valid(): form.instance.trader = request.user form.save() messages.success(request, "记录已更新") return redirect("/") else: form = EntryForm(instance=entry) context = {'form': form, 'entry': entry} return render(request, "single_entry.html", context)
3. 优化过滤查询(可选,代码更简洁)
利用模型中设置的related_name="entries",直接通过用户对象查询关联的Entry:
def get(self, request): entries = request.user.entries.all().order_by("entered_date") form = EntryForm() return render(request, "entries.html", {"form":form, "entries":entries})
4. 修复SingleEntryDeleteView的权限问题(可选)
添加权限验证,确保用户只能删除自己的Entry:
from django.http import Http404 class SingleEntryDeleteView(LoginRequiredMixin, DeleteView): template_name = "single_entry.html" model = Entry success_url = reverse_lazy("index") def get_object(self, queryset=None): obj = super().get_object(queryset) if obj.trader != self.request.user: messages.error(self.request, "你没有权限删除此记录") raise Http404("无权限访问") return obj def delete(self, request, *args, **kwargs): messages.success(self.request, "记录已删除") return super().delete(request, *args, **kwargs)
验证步骤
- 重新创建一条交易记录,确认数据库中
Entry.trader_id等于当前登录用户ID; - 登录该用户,查看首页是否显示刚创建的记录;
- 尝试编辑/删除其他用户的记录,验证权限控制是否生效。
内容的提问来源于stack exchange,提问作者Andre Di Carlo
相关产品推荐
相关产品推荐

