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

Django ListView:如何展示指定条目并保护其余数据?

解决方法

核心思路是在视图层面加入权限校验逻辑,确保用户只能访问自己有权限查看的Squadra条目,避免通过篡改URL参数越权访问。以下是几种具体实现方式:


1. 重写ListView的get_queryset方法,结合用户权限过滤

把过滤逻辑移到视图内部,同时校验用户是否有权限访问对应tipo的条目:

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

class SquadraTableListView(LoginRequiredMixin, ListView):
    model = Squadra
    template_name = 'your_template.html'

    def get_queryset(self):
        # 获取URL传入的tipo参数
        requested_tipo = self.kwargs.get('squadra')
        
        # 示例1:仅允许超级用户访问tipo=3,普通用户只能访问1/2
        if not self.request.user.is_superuser and requested_tipo == 3:
            return Squadra.objects.none()
        
        # 示例2:如果Squadra和用户有直接关联(比如有user字段),过滤用户自己的条目
        # return Squadra.objects.filter(tipo=requested_tipo, user=self.request.user)
        
        # 基础校验:限制用户只能访问预设的合法tipo
        allowed_tipos = [1, 2]
        if requested_tipo not in allowed_tipos:
            return Squadra.objects.none()
        
        return Squadra.objects.filter(tipo=requested_tipo)

2. 用Django权限系统做细粒度控制

如果需要灵活分配不同tipo的访问权限,可以自定义模型权限,再在视图中校验:

首先在models.py中定义自定义权限:

class Squadra(models.Model):
    tipo = models.IntegerField(choices=TIPO_SQUADRA, default=1)
    # ...其他字段

    class Meta:
        permissions = [
            ("view_tipo_1", "允许查看tipo=1的队伍"),
            ("view_tipo_2", "允许查看tipo=2的队伍"),
            ("view_tipo_3", "允许查看tipo=3的队伍"),
        ]

然后在视图中检查权限:

class SquadraTableListView(LoginRequiredMixin, ListView):
    model = Squadra
    template_name = 'your_template.html'

    def get_queryset(self):
        requested_tipo = self.kwargs.get('squadra')
        # 拼接对应的权限字符串
        required_perm = f"your_app.view_tipo_{requested_tipo}"
        
        # 校验用户是否拥有该权限
        if not self.request.user.has_perm(required_perm):
            return Squadra.objects.none()
        
        return Squadra.objects.filter(tipo=requested_tipo)

3. 直接返回403禁止访问(更严格的方式)

如果用户无权限,直接抛出403错误,而不是返回空页面:

from django.views.generic import ListView
from django.contrib.auth.mixins import LoginRequiredMixin
from django.core.exceptions import PermissionDenied
from .models import Squadra

class SquadraTableListView(LoginRequiredMixin, ListView):
    model = Squadra
    template_name = 'your_template.html'

    def get_queryset(self):
        requested_tipo = self.kwargs.get('squadra')
        
        # 示例:仅"AdminGroup"组的用户能访问tipo=3
        if requested_tipo == 3 and not self.request.user.groups.filter(name='AdminGroup').exists():
            raise PermissionDenied
        
        return Squadra.objects.filter(tipo=requested_tipo)

额外建议

如果不想让用户直接看到tipo的数值,可以用UUID、slug等隐蔽标识符替代URL中的数字参数,但这只是辅助手段,核心还是要做好权限校验。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.17 22:05:20