Django ORM之ManyToMany反向查询报错

一、'int' object has no attribute 'title'

1.1、创建数据表:其中UserRole_MTM是多对多关系表

class Role(models.Model):
    title=models.CharField(verbose_name='角色名称',max_length=32)
    permission=models.ManyToManyField(verbose_name='拥有的所有权限',to='Permission',blank=True)
    # def __str__(self):
    #     return self.title
class UserInfo(models.Model):
    eid = models.CharField(verbose_name='用户编码', max_length=7,unique=True)
    username=models.CharField(verbose_name='用户名',max_length=32)
    email=models.CharField(verbose_name='邮箱',max_length=32)
    password = models.CharField(verbose_name='密码', max_length=64)
    roles=models.ManyToManyField(                 # 通过已经创建的关系表创建多对多关系。
        verbose_name='拥有的所有角色',
        to='Role',
        through='UserRole_MTM',
        through_fields=('ug_user','ug_role'),
        blank=True,
        symmetrical=False,
    )

class UserRole_MTM(models.Model):
    ug_user=models.ForeignKey('UserInfo')
    ug_role=models.ForeignKey('Role')
    class Meta:
        unique_together = [
            ('ug_user','ug_role'),
        ]

1.2、在views.py中使用_set进行反向查询Role表中的title数据

class user_role_ORM(View):
    def get(self,request):
        result=models.UserInfo.objects.filter(eid='E100002').first()
        mm=result.userrole_mtm_set.all()
        for row in mm:
            print(row.ug_role_id.title)
        return render(request,'app01_rbac_ORM.html',{'obj':obj})

1.3、由于使用row.ug_role_id.title进行反向查询错误语法,出现报错

  File "D:\views\business_logic.py", line 23, in get
    print(row.ug_role_id.title)
AttributeError: 'int' object has no attribute 'title'

1.4、所以在反向查询时,不能直接使用数据表的字段名,而要使用在models.py中定义关系时的变量名来构造查询条件

print(row.ug_role.title)

 二、多对多跨表反向查询

QuerySet对象:当查询时使用all()产生的结果是QuerySet对象,而QuerySet对象没有_set.all()反向查询的属性

obj=models.UserInfo.objects.all()        #<class 'django.db.models.query.QuerySet'>

UserInfo对象:当查询时使用all().first()产生的结果时数据表对象,数据表对象有_set.all()反向查询属性

obj=models.UserInfo.objects.all().first()      # <class 'rbac.models.UserInfo'>

所以跨表多对多反向查询只能对数据表对象起作用

obj=models.UserInfo.objects.all().first()
for row in obj1.userrole_mtm_set.all():
      print(row.ug_role.title)    # row.ug_role对应的是关系表中用于指向第三张表role中id的外键。row.ug_role.title则通过这个关系表将第三张表中的title显示出来。

查询的结果是:
CEO

 三、'str' object has no attribute '_meta'

在使用ManyToMany创建三个表之间关联时报错,将Dept表中多对多关系去掉以后三个表都可以makemigrations,怀疑Dept表中有字符串和某些关键字重复,将三个表中的Permissions改为其他字符串后报错消失了。

class Dept(models.Model):
    deptNo=models.CharField(max_length=20)
    uDept_Ps=models.ManyToManyField(
        verbose_name='部门拥有的权限路由',
        to='Permissions',             # 改为Pmsn
        through='DeptPmsn_MTM',
        through_fields=('ug_dept_ps','ug_permissions'),
        # blank=True,
        # symmetrical=False,
    )
class Permissions(models.Model):      # 改为Pmsn
    permission_name=models.CharField(max_length=32,verbose_name='权限名称')
    url_routing=models.CharField(max_length=128,verbose_name='路由')

class DeptPmsn_MTM(models.Model):
    ug_dept_ps=models.ForeignKey('Dept')
    ug_permissions=models.ForeignKey('Permissioins')    # 改为Pmsn
posted @ 2020-12-13 17:30  yehaita  阅读(1180)  评论(0)    收藏  举报