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

Django日记应用用户专属日记条目访问控制实现方案咨询

解决Django日记应用的用户访问控制问题

嘿,这个问题很常见,其实不需要创建新视图,只需要修改你现有的类视图,再确保模型和用户关联上就行。我一步步给你说:

第一步:确保日记模型关联到用户

首先你的Entry模型必须有一个外键指向User,这样每个日记条目才能归属到特定用户。如果还没加的话,修改models.py:

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

class Entry(models.Model):
    title = models.CharField(max_length=200)
    content = models.TextField()
    date_created = models.DateTimeField(auto_now_add=True)
    # 添加这个字段关联用户,删除用户时同时删除其所有日记
    author = models.ForeignKey(User, on_delete=models.CASCADE)

    def __str__(self):
        return self.title

改完后记得运行迁移:python manage.py makemigrations和python manage.py migrate。

第二步:修改CreateView,自动设置当前用户为作者

用户创建日记时,要自动把当前登录用户设为条目的作者,不需要让用户手动选择。修改你的ECV类:

class ECV(LoginRequiredMixin, CreateView):
    model = Entry
    fields = ["title", "content"]
    success_url = reverse_lazy("entry-list")
    template_name = 'entries\\entry_form.html'

    def form_valid(self, form):
        # 自动关联当前登录用户
        form.instance.author = self.request.user
        return super().form_valid(form)

第三步:修改ListView,只显示当前用户的日记

原来的ELV会显示所有用户的日记,现在重写get_queryset方法,只返回当前用户的条目:

class ELV(LoginRequiredMixin, ListView):
    model = Entry
    template_name = 'entries\\entry_list.html'

    def get_queryset(self):
        # 过滤出当前用户的日记,按创建时间倒序
        return Entry.objects.filter(author=self.request.user).order_by("-date_created")

第四步:给详情、编辑、删除视图添加权限校验

这一步要确保用户只能访问、修改、删除自己的日记。我们用Django提供的UserPassesTestMixin来做权限检查,同时加上LoginRequiredMixin确保只有登录用户能访问这些视图:

首先导入需要的Mixin:

from django.contrib.auth.mixins import LoginRequiredMixin, UserPassesTestMixin

然后修改各个视图类:

详情视图(EDV)

class EDV(LoginRequiredMixin, UserPassesTestMixin, DetailView):
    model = Entry
    template_name = 'entries\\entry_detail.html'

    def test_func(self):
        # 检查当前用户是否是日记的作者
        entry = self.get_object()
        return entry.author == self.request.user

更新视图(EUV)

class EUV(LoginRequiredMixin, UserPassesTestMixin, UpdateView):
    model = Entry
    fields = ["title", "content"]
    template_name = 'entries\\entry_update_form.html'

    def get_success_url(self):
        return reverse_lazy("entry-detail", kwargs={"pk": self.object.pk})

    def test_func(self):
        entry = self.get_object()
        return entry.author == self.request.user

删除视图(EntryDeleteView)

class EntryDeleteView(LoginRequiredMixin, UserPassesTestMixin, DeleteView):
    model = Entry
    success_url = reverse_lazy("entry-list")
    template_name = 'entries\\entry_delete.html'

    def test_func(self):
        entry = self.get_object()
        return entry.author == self.request.user

关于你的疑问

  • 是否需要创建新视图? 完全不需要,只需要修改现有类视图的逻辑就行,Django的类视图扩展性很强。
  • 是否和用户会话有关? 底层是有关的,Django通过会话来跟踪当前登录的用户(也就是self.request.user),但你不需要直接操作会话,用Django自带的认证工具就足够了。

这样修改后,每个用户只能看到、编辑、删除自己的日记条目,未登录用户会被重定向到登录页,尝试访问不属于自己的条目会返回403禁止访问的页面。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.27 14:12:47