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

Django用户目标列表权限问题:实现仅用户可见个人目标

解决目标列表仅对创建者可见的问题

看起来你遇到了一个很常见的权限控制问题——你的Goal模型目前没有和用户建立关联,数据库里的目标没有归属信息,自然没法区分哪个目标属于哪个用户。咱们一步步来修复这个问题:

第一步:给Goal模型添加用户关联字段

首先要修改你的Goal模型,添加一个外键字段关联Django的用户模型,这样每个目标都能记录自己的创建者。如果用的是Django内置的User模型,代码可以这么写:

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

class Goal(models.Model):
    title = models.CharField(max_length=200)  # 补全你已有的其他字段
    # 添加创建者关联,on_delete设置为CASCADE意味着用户删除时其目标也会被删除
    creator = models.ForeignKey(User, on_delete=models.CASCADE, related_name="user_goals")
    # 可以再加个创建时间字段,方便排序
    created_at = models.DateTimeField(auto_now_add=True)

    def __str__(self):
        return self.title

修改完模型后,别忘了执行数据库迁移,让改动生效:

python manage.py makemigrations
python manage.py migrate

第二步:创建目标时自动绑定当前用户

接下来要确保用户创建目标时,系统自动把当前登录用户赋值给creator字段,不能让用户手动选择(避免权限问题)。这里分两种视图类型给你示例:

函数视图写法

from django.shortcuts import render, redirect
from django.contrib.auth.decorators import login_required
from .models import Goal
from .forms import GoalForm  # 假设你有对应的表单类

@login_required  # 确保只有登录用户能创建目标
def create_goal(request):
    if request.method == 'POST':
        form = GoalForm(request.POST)
        if form.is_valid():
            # 先不保存到数据库,先绑定用户
            new_goal = form.save(commit=False)
            new_goal.creator = request.user
            new_goal.save()
            return redirect('goal_list')  # 跳转到目标列表页
    else:
        form = GoalForm()
    return render(request, 'create_goal.html', {'form': form})

类视图(CreateView)写法

from django.views.generic.edit import CreateView
from django.contrib.auth.mixins import LoginRequiredMixin
from .models import Goal
from django.urls import reverse_lazy

class GoalCreateView(LoginRequiredMixin, CreateView):
    model = Goal
    fields = ['title']  # 这里只列出需要用户输入的字段,不要包含creator
    success_url = reverse_lazy('goal_list')

    def form_valid(self, form):
        # 绑定当前登录用户到目标的creator字段
        form.instance.creator = self.request.user
        return super().form_valid(form)

第三步:列表页只显示当前用户的目标

最后一步,修改目标列表视图,只查询当前用户创建的目标,而不是取出所有目标:

函数视图写法

from django.shortcuts import render
from django.contrib.auth.decorators import login_required
from .models import Goal

@login_required
def goal_list(request):
    # 过滤出当前用户的所有目标
    user_goals = Goal.objects.filter(creator=request.user)
    return render(request, 'goal_list.html', {'goals': user_goals})

类视图(ListView)写法

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

class GoalListView(LoginRequiredMixin, ListView):
    model = Goal
    template_name = 'goal_list.html'
    context_object_name = 'goals'

    def get_queryset(self):
        # 重写查询方法,只返回当前用户的目标
        return Goal.objects.filter(creator=self.request.user)

额外提醒

  • 一定要给所有目标相关的视图加上登录验证(上面示例里的@login_required和LoginRequiredMixin),防止未登录用户访问或操作目标。
  • 如果你用的是自定义用户模型,记得把from django.contrib.auth.models import User替换成你自己的用户模型导入,比如from .models import CustomUser,并在ForeignKey里引用它。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.25 06:39:30