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

Django任务创建时如何仅显示当前用户创建的分类?

问题:创建任务时分类选择框仅显示当前用户的分类

需要实现:用户创建任务时,分类下拉选项仅展示自己创建的分类。例如user1创建任务时只能看到自己的“user1 category”,看不到user2创建的“user2 category”。


现有代码

模型定义

class Tasks(models.Model):
    title = models.CharField(max_length=75)
    user = models.ForeignKey(User, on_delete=models.CASCADE, related_name="creator", editable=False)
    # 注:原代码缺少category外键,需补充才能关联分类
    category = models.ForeignKey(Category, on_delete=models.SET_NULL, null=True, blank=True, related_name="tasks")

class Category(models.Model):
    title = models.CharField(max_length=30, db_index=True, verbose_name="category_name")
    user = models.ForeignKey(User, on_delete=models.CASCADE, related_name="category_creator", editable=False)

视图定义

class TaskCreateView(CreateView):
    form_class = TaskForm
    template_name = 'main/add_task.html'

    def form_valid(self, form):
        form.instance.user = self.request.user
        return super(TaskCreateView, self).form_valid(form)

    def get_queryset(self):
        return Tasks.objects.filter(user=self.request.user)

错误尝试分析

你之前的代码存在几个关键问题:

  1. Tasks模型未定义category外键,导致表单中无法渲染分类选择字段
  2. 错误地从Tasks模型反向过滤分类,应该直接从Category模型查询当前用户的分类
  3. 表单的__init__方法无法直接获取self.request,需要从视图主动传递用户信息
# 错误代码示例
class TaskForm(forms.ModelForm):
    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        # 错误点:关联查询逻辑错误,且无法直接获取self.request
        self.fields['category'].queryset = Tasks.objects.filter(category__category__user=self.request.user)
        self.fields['category'].empty_label = "Not selected"

    class Meta:
        model = Tasks
        fields = ['title', 'category']

正确解决方案

步骤1:补全Tasks模型的category外键

先确保Tasks模型包含与Category的关联字段,否则表单无法渲染分类选择框。

步骤2:修改视图传递用户信息到表单

在TaskCreateView中重写get_form_kwargs方法,将当前登录用户传递给表单:

class TaskCreateView(CreateView):
    form_class = TaskForm
    template_name = 'main/add_task.html'

    def form_valid(self, form):
        form.instance.user = self.request.user
        return super().form_valid(form)

    def get_form_kwargs(self):
        # 获取默认的表单参数
        kwargs = super().get_form_kwargs()
        # 添加当前用户到参数中
        kwargs['user'] = self.request.user
        return kwargs

步骤3:修改表单过滤分类选项

在TaskForm的__init__方法中接收用户参数,过滤出该用户创建的分类:

class TaskForm(forms.ModelForm):
    def __init__(self, *args, user=None, **kwargs):
        super().__init__(*args, **kwargs)
        # 仅显示当前用户的分类
        if user:
            self.fields['category'].queryset = Category.objects.filter(user=user)
        self.fields['category'].empty_label = "未选择"

    class Meta:
        model = Tasks
        fields = ['title', 'category']

这样设置后,用户创建任务时,分类下拉框只会展示自己创建的分类,完全符合需求。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.25 01:57:47