Django中Portfolio模型用户专属股票展示问题求助
Hey there! Let's break down the issues in your code step by step and fix them so users can only see their own stocks and the display works correctly.
1. 表单初始化参数顺序错误
你的PortfolioForm的__init__方法把user作为第一个参数,但在视图里实例化表单时,你把request.POST放在了request.user前面,这会导致参数传递错位,表单无法正确绑定当前用户。
修复后的视图POST部分代码:
if request.method == 'POST': # 注意参数顺序:先传user,再传POST数据 form = PortfolioForm(request.user, request.POST or None) if form.is_valid(): ticker = form.save(commit=False) ticker.user = request.user ticker.save() return redirect('/add_stock')
2. 表单中不必要的QuerySet限制
你的PortfolioForm是用来添加新股票的,但你在__init__里把ticker字段的queryset设置为当前用户已有的股票,这会让字段变成下拉选择框,只能选已有的股票,完全不符合"添加新股票"的需求。直接去掉这行代码即可。
修复后的表单代码:
class PortfolioForm(forms.ModelForm): class Meta(): model = Portfolio fields = ['ticker'] def __init__(self, user, *args, **kwargs): super(PortfolioForm, self).__init__(*args, **kwargs) # 删掉错误的queryset限制代码 # self.fields['ticker'].queryset = Portfolio.objects.filter(user=user)
如果你的需求是让用户从已有选项中选择,那另当别论,但根据你的描述是"添加股票",所以这行是错误的。
3. GET请求时查询用户股票的逻辑错误
你在GET请求里用Portfolio.objects.filter(pk = request.user.id),这是在查询Portfolio的主键等于用户ID的记录,逻辑完全错误。正确的方式是通过外键user关联,过滤出属于当前用户的Portfolio记录。
同时,你在循环里写了output.append(str(ticker)),这里的ticker是整个查询集,应该用ticker_item来获取单个对象的字符串。
修复后的视图GET部分代码:
else: # 正确过滤当前用户的股票 user_stocks = Portfolio.objects.filter(user=request.user) output = [] for stock in user_stocks: # 用单个stock对象而不是整个查询集 output.append(str(stock)) return render(request, 'test_app/add_stock.html', {'ticker': user_stocks, 'output': output})
4. 可选优化:调整related_name语义
你的Portfolio模型里user字段的related_name='investor'语义不太准确,通常related_name用来表示从User反向查询Portfolio的名称,改成related_name='portfolios'会更直观,这样你可以用request.user.portfolios.all()直接获取当前用户的所有股票,让代码更简洁:
class Portfolio(models.Model): ticker = models.CharField(max_length=15) # 修改为更语义化的related_name user = models.ForeignKey(User, on_delete=models.CASCADE, related_name='portfolios', null=True) def __str__(self): return self.ticker
之后GET请求里可以简化为:
user_stocks = request.user.portfolios.all()
做完这些修改后,用户添加的股票会正确关联到自己的账户,页面也只会展示当前用户的股票,显示问题也会解决。
内容的提问来源于stack exchange,提问作者Francois Jack

