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

Django过滤用户记录 仅向登录用户展示其自有数据的实现方法

Django多对多中间表表单下拉选项用户权限过滤方案

适用场景

  • 项目中采用自定义中间表实现多对多模型关联
  • 需要渲染带下拉选择框的表单,供用户选择关联项完成中间表数据插入
  • 需要做数据权限控制:下拉菜单仅展示当前登录用户有权限查看的自有记录,过滤依据为当前登录用户的主键ID

核心实现思路

在表单类初始化阶段动态传入当前登录用户ID,覆写关联模型选择字段的查询集,从数据源层面完成权限过滤,从根源上避免用户越权选择其他用户的数据。

各层代码实现

models.py(中间表模型定义)

class ActivityEvidence(models.Model):
    activity = models.ForeignKey(Activity, on_delete=models.CASCADE)
    evidence = models.ForeignKey(Evidence, on_delete=models.CASCADE)
    class Meta:
        unique_together = (('activity', 'evidence'),)
    def __str__(self):
        return f'{self.activity}, {self.evidence}'

模型层通过unique_together添加活动与素材的联合唯一约束,避免重复插入相同关联关系产生脏数据。

views.py(视图层传参)

# 实例化表单时传入当前登录用户ID
context['form'] = LinkEvidenceForm(user=request.user.id)

forms.py(表单层动态过滤选项)

class LinkEvidenceForm(forms.Form):
   def __init__(self, *args, **kwargs):
      # 从初始化参数中取出传入的用户ID
      user = kwargs.pop('user', None)
      super(LinkEvidenceForm, self).__init__(*args, **kwargs)
      # 动态定义素材下拉字段,仅查询当前用户所属素材并按名称排序
      self.fields['evidence_id'] = forms.ModelChoiceField(queryset=Evidence.objects.filter(teacher=user).order_by('evidence_name'))
      # 动态定义活动下拉字段,仅查询当前用户所属活动并按名称排序
      self.fields['activity_id'] = forms.ModelChoiceField(queryset=Activity.objects.filter(teacher=user).order_by('activity_name'))

实现说明

  • 表单初始化时先通过kwargs.pop取出自定义传入的user参数,避免多余参数传递给父类Form的构造方法触发参数错误
  • 两个下拉选择字段使用ModelChoiceField,直接绑定过滤后的模型查询集,无需额外手动拼接选项
  • 查询集增加按名称排序的规则,优化下拉选项的展示顺序

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.28 22:57:25