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

Django:如何为用户/组设置Model实例的限时查看权限

解决Django中带过期时间的Item实例访问权限控制问题

嘿,作为Django新手碰到这种自定义权限的需求完全正常,官方默认的权限系统确实没法直接覆盖“按实例+时间过期”的场景,咱们一步步来实现这个功能:

1. 先设计权限关联模型

首先需要一个中间模型,用来记录每个用户对每个Item的访问权限及过期时间。在你的models.py里添加:

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

class Item(models.Model):
    # 这里是你原有的Item模型字段,比如:
    name = models.CharField(max_length=100)
    content = models.TextField()

class ItemAccessPermission(models.Model):
    user = models.ForeignKey(User, on_delete=models.CASCADE, related_name="item_permissions")
    item = models.ForeignKey(Item, on_delete=models.CASCADE, related_name="access_permissions")
    expiration_time = models.DateTimeField()
    created_at = models.DateTimeField(auto_now_add=True)

    class Meta:
        # 确保一个用户对同一个Item只有一条权限记录
        unique_together = ('user', 'item')

    def is_valid(self):
        # 判断权限是否有效(未过期)
        return self.expiration_time > timezone.now()

2. 重写DetailView的权限验证逻辑

接下来修改你的DetailView,在获取Item实例前先检查当前用户是否拥有有效的访问权限。如果没有权限或者权限已过期,直接抛出权限拒绝的异常:

from django.views.generic.detail import DetailView
from django.core.exceptions import PermissionDenied
from .models import Item, ItemAccessPermission
from django.utils import timezone

class ItemDetailView(DetailView):
    model = Item
    template_name = 'item_detail.html'  # 替换成你的模板路径

    def get_object(self, queryset=None):
        # 先获取要展示的Item实例
        obj = super().get_object(queryset=queryset)
        # 检查当前用户是否有有效的访问权限
        try:
            permission = ItemAccessPermission.objects.get(user=self.request.user, item=obj)
            if not permission.is_valid():
                raise PermissionDenied("您对该Item的访问权限已过期")
        except ItemAccessPermission.DoesNotExist:
            raise PermissionDenied("您没有访问该Item的权限")
        return obj

3. 权限的授予与管理

现在你需要有给用户分配权限的方式,比如:

  • 在Django后台管理中注册ItemAccessPermission模型,手动添加权限记录
  • 写一个视图来批量/手动分配权限,比如:
from django.shortcuts import get_object_or_404, redirect
from .models import Item, ItemAccessPermission
from django.utils import timezone
from datetime import timedelta

def grant_item_access(request, item_id):
    # 示例:给当前用户分配该Item的7天访问权限
    item = get_object_or_404(Item, id=item_id)
    # 先检查是否已有权限,有就更新过期时间,没有就创建
    permission, created = ItemAccessPermission.objects.get_or_create(
        user=request.user,
        item=item,
        defaults={'expiration_time': timezone.now() + timedelta(days=7)}
    )
    if not created:
        permission.expiration_time = timezone.now() + timedelta(days=7)
        permission.save()
    return redirect('item_detail', pk=item_id)

4. 前端提示优化(可选)

如果想在模板里更友好地提示用户权限状态,可以在视图里把权限信息传递到模板:

def get_context_data(self, **kwargs):
    context = super().get_context_data(**kwargs)
    permission = ItemAccessPermission.objects.get(user=self.request.user, item=self.object)
    context['permission_expiration'] = permission.expiration_time
    return context

然后在模板里显示:

<p>该Item访问权限将于:{{ permission_expiration|date:"Y-m-d H:i" }} 过期</p>

这样就能实现你要的“每个用户对指定Item的访问权限在指定时间后过期,过期无法查看”的需求啦~

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.21 08:23:32