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

Django类视图中如何正确获取用户ID过滤Question模型数据?

我来帮你搞定这个卡了你两天的问题!你遇到的核心问题是把Flask的用法套到Django上了,另外模型字段的设计也有可以优化的地方,咱们一步步来解决:

1. 先修复视图的用户获取错误

Django类视图和Flask的函数视图逻辑不一样,类视图里的请求对象是实例的属性,要通过self.request获取,而不是把request作为方法参数。另外一定要确保用户已登录,避免匿名用户的情况,推荐用LoginRequiredMixin做登录校验:

from django.contrib.auth.mixins import LoginRequiredMixin
from django.views.generic import ListView
from .models import Question

class VotesView(LoginRequiredMixin, ListView):
    template_name = 'polls/votes.html'
    model = Question

    def get_queryset(self):
        # 获取当前登录用户的ID
        current_user_id = self.request.user.id
        # 过滤出当前用户有权查看的问题
        # 注意转成字符串,因为MultiSelectField存的是逗号分隔的字符串
        return Question.objects.filter(authorized__contains=str(current_user_id))
2. 修正模型中MultiSelectField的选项问题

你现在的users = User.objects.values_list('id','username')会在模型加载时就执行数据库查询,后续新增的用户根本不会出现在下拉选项里!应该把choices设置成一个可调用对象,这样每次渲染表单时都会动态拉取最新的用户列表:

from django.db import models
from django.contrib.auth.models import User
from multiselectfield import MultiSelectField  # 假设你用的是django-multiselectfield库

class Question(models.Model):
    question_text = models.CharField(max_length=200)
    pub_date = models.DateTimeField('date published')
    # 用lambda作为可调用对象,动态获取用户选项
    authorized = MultiSelectField(
        choices=lambda: User.objects.values_list('id', 'username'),
        null=True,
        blank=True
    )

    def __str__(self):
        return self.question_text
3. 更专业的方案:用ManyToManyField替代MultiSelectField

其实用MultiSelectField存用户ID列表并不是最佳实践——它把多个值塞在单个字段里,查询容易出歧义(比如用户ID是1,会误匹配到ID 11的用户),而且不利于后续维护。Django推荐用ManyToManyField来处理这种多对多的关联关系,数据库层面的关联查询更准确高效:

修改后的模型:

from django.db import models
from django.contrib.auth.models import User

class Question(models.Model):
    question_text = models.CharField(max_length=200)
    pub_date = models.DateTimeField('date published')
    # 用ManyToManyField关联用户,自动维护中间表
    authorized = models.ManyToManyField(
        User,
        related_name='authorized_questions',
        blank=True,
        help_text="选择有权查看该问题的用户"
    )

    def __str__(self):
        return self.question_text

对应的视图过滤代码(更简洁准确):

def get_queryset(self):
    return Question.objects.filter(authorized=self.request.user)
最后解释下你遇到的报错原因
  • 第一个报错AttributeError: 'VotesView' object has no attribute 'user':因为你把request作为get_queryset的参数,但Django调用这个方法时根本不会传这个参数,导致方法里的request其实是视图实例本身(也就是self),自然找不到user属性。
  • 第二个报错是因为在没有HTTP请求上下文的场景下调用了视图(比如测试时),但只要修复了视图的request获取方式,并且确保用户登录,这个问题会自动消失。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.28 07:17:23