1.先看model的定义
user表:
class User(models.Model):
"""
用户表
"""
username = models.CharField(verbose_name='用户名', max_length=32)
password = models.CharField(verbose_name='密码', max_length=64)
email = models.EmailField(verbose_name='邮箱')
roles = models.ManyToManyField(verbose_name='拥有角色', to='Role', blank=True) def __str__(self):
return self.username
role表:
class Role(models.Model):
"""
角色表
"""
caption = models.CharField(verbose_name='角色', max_length=32)
permissions = models.ManyToManyField(verbose_name='拥有权限', to='Permission', blank=True) def __str__(self):
return self.caption
2.因为M2M建立在User表里面,所以通过user_obj获取他的所有的roles时,是正向查找,直接user_obj.roles.all()即可.
def test1(request):
obj = rbac_models.User.objects.filter(id=1).first()
print(obj.roles.all())
return HttpResponse("xxx")
>>>:<QuerySet [<Role: 销售>, <Role: 销售经理>]>
3.当通过role_obj获取所有的user时,因为M2M不在他里面,此时查询是反向查询,需要使用role_obj.user_set.all().
def test1(request):
role_obj = rbac_models.Role.objects.filter(caption="销售").first()
print(role_obj)
print(role_obj.user_set.all())
return HttpResponse("xxx")
>>>:销售
>>>:<QuerySet [<User: dabo>, <User: 大卫>, <User: 嘻嘻>]>
4.进一步理解
M2M建立在User表里面,该M2M对应的字段是roles,所以roles作为User表的字段,其对象user_obj是有roles这个属性的,所以可以直接user_obj.roles.all()查询得到所有数据.
Role表,表面上它包含2个字段caption和permissions和一个默认的id字段一共3个字段,但是其实它还包含一个M2M字段,该字段是user_set,所以它的对象才能使用role_obj.user_set.all()获取数据,代码如下:
def test1(request):
s = rbac_models.Role._meta.get_fields()
for i in s:
print(i.name)
return HttpResponse("xxx")
>>>:user id caption permissions