费了这么大劲写篇文章,最后发现还不如花时间听听火车。
‘黑色的不是夜晚,是漫长的孤单,看脚下一片黑暗,望头顶星光璀璨。’
orm: 全称Object-Relation Mapping,作用是在django中将对数据库的操作都转化成对类属性和方法的操作。
首先,在models中定义三个类,既三个数据库表,User(用户表)、Role(角色表)、Premission(权限表)

接着,插入数据,分别是用户表,角色表,权限表。当我们创建一个用户的时候,要分配相应的角色和权限。



1、本文的目标就是查询用户luka所拥有的权限(权限=url),查询语句如下。主要是弄清楚object、filter、values分别是什么意思,怎么用。
>>> curr_user = models.User.objects.filter(user='luka').first()>>> curr_premission = curr_user.role.filter().values('premission__title','premission__url')
2、通过调用models中的User类,我们发现返回的类型是django.db.models.base.ModelBase,这是因为model中的类都是ModelBase的子类,ModelBase是在django.db.models.base中定义的。因此,在modles中定义的类是ModelBase的子类,继承了ModelBase的方法,包括 'objects'等,在这不列举。
>>> obj = models.User>>> print(obj,type(obj))<class 'web.models.User'> <class 'django.db.models.base.ModelBase'>
3、前面说了User继承了一些父类,在调用父类的objects时,实际上返回的是一个models.manager.Manager对象objects。Manager类是我们通过模型类去操作数据库的工具,django给每个定义的模型默认添加一个名为objects的Manager类的对象。简单来说就是,必须通过objects来操作数据库。
>>> obj = models.User.objects>>> print(type(obj))web.User.objects <class 'django.db.models.manager.Manager'>
4、在objects后面,介绍一下get和filter方法,这两个放到一起讲是因为这两者使用方法是一样,使用情景不一样。get方法是从数据库取得一个匹配的结果,返回一个对象,有多个结果或者没有匹配结果都会报异常。
>>> get_obj = models.User.objects.get(user='luka')>>> print(get_obj,type(get_obj))monika <class 'web.models.User'>
5、filter返回一个QuerySet,以下看出有两个luka用户,QuerySet里面是User类的两个对象。
>>> filter_obj = models.User.objects.filter(user='luka')>>> print(filter_obj)<QuerySet [<User: luka>, <User: luka>]>>>> print(type(filter_obj))<class 'django.db.models.query.QuerySet'>>>> for j in filter_obj:print(j,type(j))luka <class 'web.models.User'>luka <class 'web.models.User'>
6、回到最开始的查询,filter后面加first,既获取结果的第一条,返回的是User的一个对象。
>>> curr_user = models.User.objects.filter(user='luka').first()
7、从上面可知curr_user是User的一个实例,因此可查看User类中的属性,分别有user、password、role,
>>> curr_premission = curr_user.role.filter().values('premission__title','premission__url')
8、User类中的role是一个多对多属性,关联Role类,因此在role后面加all获取全部luka关联Role结果或者filter过滤。最终,我们得到了一个QuerySet,前面说了QuerySet里面是对象,也就是我们获得了一个Role对象,对象名叫“老板”,也就是luka的角色是老板。
>>> curr_premission =curr_user.role>>> print(curr_premission,type(curr_premission))web.Role.None <class 'django.db.models.fields.related_descriptors.create_forward_many_to_many_manager.<locals>.ManyRelatedManager'>>>> curr_premission =curr_user.role.filter()>>> print(curr_premission,type(curr_premission))<QuerySet [<Role: 老板>]> <class 'django.db.models.query.QuerySet'>
9、最后,我们来看一下values的用法。values返回一个QuerySet,跟filter不一样的是,values返回的QuerySet里面是字典,其键对应于模型对象的属性名
>>> user_obj = models.User.objects.values()>>> print(user_obj)<QuerySet [{'id': 1, 'user': 'luka', 'password': '123'}, {'id': 2, 'user': 'tommy', 'password': '123'}, {'id': 3, 'user': 'jimmy', 'password': '123'}, {'id': 4, 'user': 'luka', 'password': '789'}]>>>> print(type(user_obj))<class 'django.db.models.query.QuerySet'>>>> for i in user_obj:print(i,type(i)){'id': 1, 'user': 'luka', 'password': '123'} <class 'dict'>{'id': 2, 'user': 'tommy', 'password': '123'} <class 'dict'>{'id': 3, 'user': 'jimmy', 'password': '123'} <class 'dict'>{'id': 4, 'user': 'luka', 'password': '789'} <class 'dict'>>>> user_obj = models.User.objects.values('id','password')>>> print(user_obj)<QuerySet [{'id': 1, 'password': '123'}, {'id': 2, 'password': '123'}, {'id': 3, 'password': '123'}, {'id': 4, 'password': '789'}]>>>> user_obj = models.User.objects.values().filter(id=1)>>> print(user_obj)<QuerySet [{'id': 1, 'user': 'luka', 'password': '123'}]>>>> print(type(user_obj))<class 'django.db.models.query.QuerySet'>
10、回到序号1中的两个查询语句,从序号8中可知我们得到了一个Role的对象,因此可用values查询Role对象中的属性,分别有name、premission。因为premission是多对对属性,可通过两个下划线获取关联的类对象的属性。
>>> curr_premission = curr_user.role.filter().values('premission__title','premission__url')print(curr_premission,type(curr_premission))<QuerySet [{'premission__title': '客户列表', 'premission__url': '/customer/list/'}, {'premission__title': '添加客户', 'premission__url': '/customer/add/'}, {'premission__title': '修改客户', 'premission__url': '/customer/edit/(?P<cid>\\d+)/'}, {'premission__title': '批量导入', 'premission__url': '/customer/import/'}, {'premission__title': '下载模板', 'premission__url': '/customer/tpl/'}, {'premission__title': '删除客户', 'premission__url': '/customer/list/(?P<cid>\\d+)/'}]> <class 'django.db.models.query.QuerySet'>
11、将luka用户所属权限url放入列表。
>>> pre_list = [i['premission__url'] for i in curr_premission]>>> print(pre_list)['/customer/list/', '/customer/add/', '/customer/edit/(?P<cid>\\d+)/', '/customer/import/', '/customer/tpl/', '/customer/list/(?P<cid>\\d+)/']




