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

Django表单问题:如何仅展示当前登录用户创建的Deck选项

解决GameForm仅显示当前用户Deck的问题

方法一:在视图中动态设置表单字段的QuerySet

直接在视图里修改表单deck字段的可选范围,确保只加载当前用户创建的Deck:

修改views.py:

from django.contrib.auth.decorators import login_required
from django.shortcuts import render, HttpResponseRedirect

@login_required  # 确保只有登录用户能访问
def game_tracker(request):
    user_decks = Deck.objects.filter(user=request.user)
    if request.method == "POST":
        form = GameForm(request.POST)
        # 为POST请求也设置QuerySet,保证表单验证逻辑一致
        form.fields['deck'].queryset = user_decks
        if form.is_valid():
            form.save()  # 保存表单数据
            return HttpResponseRedirect('/track')
    else:
        form = GameForm()
        # 初始化表单时过滤Deck选项
        form.fields['deck'].queryset = user_decks

    context = {'form': form}
    return render(request, 'gametracker_app/gametracker.html', context)

方法二:封装表单逻辑,支持传入用户参数

把过滤逻辑封装到表单类中,让表单更具复用性:

修改forms.py:

from django import forms
from .models import Game, Deck

class GameForm(forms.ModelForm):
    class Meta:
        model = Game
        exclude = {'date', 'time', }
        labels = {
            'deck': 'What deck',
            'num_players': '# of Players',
            'start_pos': 'Starting position',
            'mull': 'Starting hand',
            'outcome': 'Outcome',
            'wincon': 'Wincon',
            'medium': 'Paper or Online',
            'tournament': 'Tournament',
        }

    def __init__(self, *args, **kwargs):
        # 从参数中取出当前用户
        self.user = kwargs.pop('user', None)
        super().__init__(*args, **kwargs)
        # 如果用户存在,过滤Deck选项
        if self.user:
            self.fields['deck'].queryset = Deck.objects.filter(user=self.user)

修改views.py:

from django.contrib.auth.decorators import login_required
from django.shortcuts import render, HttpResponseRedirect
from .forms import GameForm

@login_required
def game_tracker(request):
    if request.method == "POST":
        # 实例化表单时传入当前用户
        form = GameForm(request.POST, user=request.user)
        if form.is_valid():
            form.save()
            return HttpResponseRedirect('/track')
    else:
        form = GameForm(user=request.user)

    context = {'form': form}
    return render(request, 'gametracker_app/gametracker.html', context)

注意事项

  • 添加@login_required装饰器可以避免未登录用户访问时出现request.user为空的错误;
  • 两种方法都能实现需求,方法二更符合Django的MVC设计思想,适合需要在多个视图复用该表单的场景。

内容的提问来源于stack exchange,提问作者bld-sync

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.05 21:18:18