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

Django Admin如何创建自定义权限 限制用户仅访问外键关联数据

Django Admin 实现关联用户的行级数据权限方案

默认Django为模型自动生成的add/change/delete/view属于模型级权限,用户只要获得对应权限就能访问模型下的全部数据,要实现「用户仅查看外键关联到自身的对象」的效果,不需要引入第三方依赖,直接重写模型Admin类的对应方法即可,以题目中的Book模型为例,完整实现如下:

核心实现逻辑

一共需要做三层拦截,覆盖所有访问场景:

  • 列表页查询集过滤:只返回关联到当前用户的对象
  • 单对象权限校验:防止用户通过手动拼接URL访问不属于自己的对象详情、编辑、删除页
  • 新增数据自动绑定:保存数据时自动将关联用户字段设为当前登录用户,避免越权绑定到其他用户

完整代码示例

在对应app的admin.py中添加如下代码:

from django.contrib import admin
from .models import Book

@admin.register(Book)
class BookAdmin(admin.ModelAdmin):
    # 编辑/新增页不展示作者选择项,避免用户越权修改所属作者
    exclude = ('author',)

    def get_queryset(self, request):
        """重写列表页查询集,过滤非当前用户的图书数据"""
        qs = super().get_queryset(request)
        # 超级用户可查看所有数据,不受限制
        if request.user.is_superuser:
            return qs
        # 普通用户仅返回作者为当前登录用户的图书
        return qs.filter(author=request.user)

    def has_view_permission(self, request, obj=None):
        """校验单对象查看权限"""
        base_perm = super().has_view_permission(request, obj)
        if not base_perm:
            return False
        # 列表页访问直接放行,由get_queryset做数据过滤
        if obj is None:
            return True
        # 仅作者本人或超管可查看单本图书详情
        return obj.author == request.user or request.user.is_superuser

    def has_change_permission(self, request, obj=None):
        """校验单对象编辑权限"""
        base_perm = super().has_change_permission(request, obj)
        if not base_perm:
            return False
        if obj is None:
            return True
        return obj.author == request.user or request.user.is_superuser

    def has_delete_permission(self, request, obj=None):
        """校验单对象删除权限"""
        base_perm = super().has_delete_permission(request, obj)
        if not base_perm:
            return False
        if obj is None:
            return True
        return obj.author == request.user or request.user.is_superuser

    def save_model(self, request, obj, form, change):
        """保存图书时自动绑定当前登录用户为作者"""
        # 仅新增时设置作者,避免编辑时修改原有归属
        if not change:
            obj.author = request.user
        super().save_model(request, obj, form, change)

使用说明

  • 权限分配逻辑和原生Django权限完全一致,直接给对应用户分配Book模型的查看、编辑等基础权限即可,不需要额外创建自定义权限
  • 超级用户默认拥有全部权限,可查看、编辑所有图书数据,符合常规后台使用逻辑
  • 所有访问入口均做了权限拦截,不存在越权访问漏洞

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.28 06:51:07