关于ManyToMany的一点补充

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
View Code

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
View Code

 

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
 
 
  
posted @ 2017-10-27 14:23  jec1999  阅读(113)  评论(0编辑  收藏  举报