多对多交集过滤
group = models.ManyToManyField(Group, verbose_name='可见分组',help_text='可见分组',blank=True,related_name='MerchSet_group')
d django的ManyToManyField字段会自动创建两张表的关联表,在模型创建中比较省事,在使用过程中,会出现需要交集过滤的数据,可以按如下方式处理
案例
- 共有分组【g1,g2,g3,g4,g5,g6,g7,g8,g9,g10】
- 有MerchSet模型实例【m1,m2,m3,m4,m5】
- 设置模型实例多对多的分组为
- m1:g1,g2,g3
- m2:g1,
- m3:g2
- m4:g3
- m5:g4
- 设置用户A的权限分组为【g1,g2,g3】
- 当模型按用户权限分钟进行行过滤,则按逻辑应可以看到【m1,m2,m3,m4】
实际过程
- 获取用户权限分组
groups = [g1,g2,g3]
- 使用包含语句查询
MerchSet.object.filter(group__in=groups)
-
d 实际查询出来的结果为
[m1,m1,m1,m2,m3,m4]
,m1实例会因为权限重复而出现多次
并导致django get() returned more than one MerchSet -- it returned 2!
解决办法-使用反选
- 用户所在分组为
groups = [g1,g2,g3]
- 用户不可见的数据为
ungroups = MerchSet.object.exclude(group__in=groups)
,即[m5]
-
s 那除去用户不可见的数据,剩余都是可见数据
[m1,m2,m3,m4]
data = MerchSet.object.exclude(id__in=ungroups)
实例:改写admin
get_queryset(self, request)
ungroups = super(MerchSetAdminModel, self).get_queryset(request).filter(deleted=0).exclude(group__in=qs)
return super(MerchSetAdminModel, self).get_queryset(request).filter(deleted=0).exclude(id__in=ungroups)