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
 
 
  

关于ManyToMany的一点补充的更多相关文章

  1. 对于Tomcat服务器环境变量和启动配置的一点补充

    我们之前第一次使用Tomcat服务器运行jsp应用时,曾经给Tomcat配置过一个环境变量CATALINA_HOME,这个变量指定了Tomcat的安装位置,对于多个开发项目,我们一般会释放多个tomc ...

  2. WCF的一点补充-Restful相关

    参考 配置WCF心得 对REST架构 风格下WCF的一点补充 Securing WCF REST Service with Azure AppFabric Access Control Service ...

  3. C++基础--引用的一点补充

    这一篇是对引用的一点补充,内容基本上是来自<C++ primer plus>一书第八章的内容. 前面一篇介绍了引用的一点特点,这里补充一个,将引用用于类对象的时候,有一个体现继承的特征,就 ...

  4. Android 12(S) 图形显示系统 - Surface 一点补充知识(十二)

    必读: Android 12(S) 图形显示系统 - 开篇 一.前言 因为个人工作主要是Android多媒体播放的内容,在工作中查看源码或设计程序经常会遇到调用API: static inline i ...

  5. 关于bundle install 的一点补充

    在第一次运行bundle install之后,生成了Gemfile.lock文件,里面记录gem的具体版本号,按照官方文档说明,以后运行bundle install就不会再依据Gemfile,而是根据 ...

  6. 20151217--Ajax的一点补充

    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/ ...

  7. 【Linux】 linux的进程系统一点补充

    linux进程系统 ■ 程序 vs. 进程 程序静态地存放在磁盘中.用户可以触发执行程序,被触发后的程序就存进内存中成为一个个体,即为进程. 有些进程(比如crond需要每分钟都扫描.守护进程等等)是 ...

  8. 关于SpringMVC控制器的一点补充

    首先复习一下之前控制器的写法:http://www.cnblogs.com/eco-just/p/7882016.html. 我们可以看到,之前的写法是这样的: @RequestMapping(&qu ...

  9. 关于前一篇innodb自增列自己的一点补充

    上篇文章是我转载的,忘记注明了出处,在这里深感歉意.但是上篇文章中关于自增列预留ID的计算我当时怎么弄明白,后来自己想了想终于想通了,在这里详细解释一下. 我们以一次性插入10行为例,表格如下:  插 ...

随机推荐

  1. 【转】Https内部机制基础知识

    互联网权威机构 - CA 机构,又称为证书授权 (Certificate Authority) 机构,浏览器会内置这些"受信任的根证书颁发机构" (即 CA). 数字证书 提及 H ...

  2. 用python做数值计算

    http://sebug.net/paper/books/scipydoc/scipy_intro.html http://www.cnblogs.com/weilq/p/3432817.html h ...

  3. Eclipse下配置TinyOS开发环境

    通过给Eclipse安装Yeti 2 - TinyOS 2 Plugin for Eclipse来配置TinyOS IDE,从而可建立TinyOS Project Yeti 2的介绍请参考网站:htt ...

  4. 201621123008 《Java程序设计》第二周学习总结

    1. 本周学习总结 通过查询API掌握了一下几种类的基本用法: String类 StringBuilder类 ArrayList类 BigInteger类 BigDecimal类 Arrays类 认知 ...

  5. attempt to create delete event with null entity

    解决办法:删除之前判断是否为空 if(Object != null){ session.delete(Object); }

  6. SEO方式之HTTPS 访问优化详解

    SEO到底要不要做HTTPS?HTTPS对SEO的重要性 正方观点 1.HTTPS具有更好的加密性能,避免用户信息泄露: 2.HTTPS复杂的传输方式,降低网站被劫持的风险: 3.搜索引擎已经全面支持 ...

  7. Vim配置(转)

    1.按F5可以直接编译并执行C.C++.java代码以及执行shell脚本,按“F8”可进行C.C++代码的调试 2.自动插入文件头 ,新建C.C++源文件时自动插入表头:包括文件名.作者.联系方式. ...

  8. Notification的功能和用法 加薪通知

    实现通知栏消息的生成和消除 MainActivity.java        public class MainActivity extends Activity   {       static f ...

  9. 大文件上传插件webupload插件

    版权所有 2009-2018荆门泽优软件有限公司 保留所有权利 官方网站:http://www.ncmem.com/ 产品首页:http://www.ncmem.com/webapp/up6.2/in ...

  10. 判断Mouse事件源类型

    //鼠标事件源类型 public enum MouseEventSource { Mouse, Pen, Touch } /// <summary> /// MainWindow.xaml ...