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

使用django-guardian限制仅父模型所有者可在Django通用视图下创建子模型

基于django-guardian的规范实现方案

核心思路

复用你已有的django-guardian对象权限体系,通过guardian提供的对象权限校验混入类,在请求进入视图早期完成Parent归属校验,替代手动写的权限判断逻辑,和Parent模型CRUD的权限控制逻辑保持统一。

前置准备

确保你在创建Parent实例时,已经给创建者分配了对应实例的manipulate权限,示例代码如下(加在Parent的CreateView的form_valid逻辑中即可):

from guardian.shortcuts import assign_perm

# Parent实例创建成功后添加
assign_perm("你的应用名.manipulate_parent", request.user, parent实例)

注意Django会自动给模型自定义权限的codename加上_模型名小写后缀,所以你定义的manipulate权限对应的完整codename是manipulate_parent。

优化后的完整代码

views.py

from django.views.generic.edit import CreateView
from django.contrib.auth.mixins import LoginRequiredMixin
from django.urls import reverse_lazy
from django.forms import ModelForm
from guardian.mixins import ObjectPermissionRequiredMixin
from . import models

class CreateChildForm(ModelForm):
    class Meta:
        fields = ('name',) # 直接移除parent字段,彻底避免表单篡改风险
        model = models.Child

class CreateChild(LoginRequiredMixin, ObjectPermissionRequiredMixin, CreateView):
    model = models.Child
    form_class = CreateChildForm
    success_url = reverse_lazy('home')
    # 配置需要校验的权限,替换为你自己的应用名
    permission_required = "你的应用名.manipulate_parent"
    # 无权限时直接返回403,不需要重定向到登录页(已通过LoginRequiredMixin校验登录状态)
    return_403 = True

    def get_permission_object(self):
        # 返回要校验权限的Parent实例,guardian会自动完成权限校验
        return models.Parent.objects.get(uuid=self.kwargs['uuid'])

    def form_valid(self, form):
        # 视图层强制绑定parent,完全避免参数篡改风险
        form.instance.parent = self.get_permission_object()
        return super().form_valid(form)

逻辑说明

  1. 权限校验逻辑前置:ObjectPermissionRequiredMixin会在视图执行任何业务逻辑前完成权限校验,无权限直接返回403,比你之前在get_form_kwargs里校验的逻辑更靠前,符合权限控制的最佳实践。如果用户传入的UUID不存在,查询Parent时会自动抛出404错误,符合预期。
  2. 彻底规避参数篡改风险:直接从表单字段中移除了parent字段,完全在视图层赋值,不会出现用户篡改隐藏字段提交的问题。
  3. 权限体系统一:和你之前Parent CRUD用的django-guardian逻辑完全一致,后续权限调整只需要修改权限定义,不需要改业务校验代码。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.02 16:27:03