django 1.7+ default_permissions
由于做Caption要做权限设计。在核心类的设计的时候需要做好权限的基础设计。django 1.7+以后 django.db.modes新增特性 default_permissions,官方文档语焉不详。
决定自己探索下,不想一一分析代码,遂引入bug,直接观察核心线路。
引入bug方法:
class baseModel(models.Model):
#....
class Meta:
default_permissions='add'#should be ('add','change',...)
错误如下:
Traceback (most recent call last):
File "C:\Users\tommy.yu\Desktop\Captain\Captain-master\codes\Captain\manage.py", line 10, in <module>
execute_from_command_line(sys.argv)
File "C:\Python27\lib\site-packages\django-1.7.2-py2.7.egg\django\core\management\__init__.py", line 385, in execute_from_command_line
utility.execute()
File "C:\Python27\lib\site-packages\django-1.7.2-py2.7.egg\django\core\management\__init__.py", line 377, in execute
self.fetch_command(subcommand).run_from_argv(self.argv)
File "C:\Python27\lib\site-packages\django-1.7.2-py2.7.egg\django\core\management\base.py", line 288, in run_from_argv
self.execute(*args, **options.__dict__)
File "C:\Python27\lib\site-packages\django-1.7.2-py2.7.egg\django\core\management\base.py", line 338, in execute
output = self.handle(*args, **options)
File "C:\Python27\lib\site-packages\django-1.7.2-py2.7.egg\django\core\management\commands\migrate.py", line 165, in handle
emit_post_migrate_signal(created_models, self.verbosity, self.interactive, connection.alias)
File "C:\Python27\lib\site-packages\django-1.7.2-py2.7.egg\django\core\management\sql.py", line 268, in emit_post_migrate_signal
using=db)
File "C:\Python27\lib\site-packages\django-1.7.2-py2.7.egg\django\dispatch\dispatcher.py", line 198, in send
response = receiver(signal=self, sender=sender, **named)
File "C:\Python27\lib\site-packages\django-1.7.2-py2.7.egg\django\contrib\auth\management\__init__.py", line 114, in create_permissions
Permission.objects.using(using).bulk_create(perms)
File "C:\Python27\lib\site-packages\django-1.7.2-py2.7.egg\django\db\models\query.py", line 409, in bulk_create
self._batched_insert(objs_without_pk, fields, batch_size)
File "C:\Python27\lib\site-packages\django-1.7.2-py2.7.egg\django\db\models\query.py", line 938, in _batched_insert
using=self.db)
File "C:\Python27\lib\site-packages\django-1.7.2-py2.7.egg\django\db\models\manager.py", line 92, in manager_method
return getattr(self.get_queryset(), name)(*args, **kwargs)
File "C:\Python27\lib\site-packages\django-1.7.2-py2.7.egg\django\db\models\query.py", line 921, in _insert
return query.get_compiler(using=using).execute_sql(return_id)
File "C:\Python27\lib\site-packages\django-1.7.2-py2.7.egg\django\db\models\sql\compiler.py", line 920, in execute_sql
cursor.execute(sql, params)
File "C:\Python27\lib\site-packages\django-1.7.2-py2.7.egg\django\db\backends\utils.py", line 81, in execute
return super(CursorDebugWrapper, self).execute(sql, params)
File "C:\Python27\lib\site-packages\django-1.7.2-py2.7.egg\django\db\backends\utils.py", line 65, in execute
return self.cursor.execute(sql, params)
File "C:\Python27\lib\site-packages\django-1.7.2-py2.7.egg\django\db\utils.py", line 94, in __exit__
six.reraise(dj_exc_type, dj_exc_value, traceback)
File "C:\Python27\lib\site-packages\django-1.7.2-py2.7.egg\django\db\backends\utils.py", line 65, in execute
return self.cursor.execute(sql, params)
File "C:\Python27\lib\site-packages\django-1.7.2-py2.7.egg\django\db\backends\sqlite3\base.py", line 486, in execute
return Database.Cursor.execute(self, query, params)
django.db.utils.IntegrityError: columns content_type_id, codename are not unique
直接在最终的文件C:\Python27\lib\site-packages\django-1.7.2-py2.7.egg\django\db\backends\sqlite3\base.py里面加入print xxx之类的语句。如下:
def execute(self, query, params=None):
if params is None:
return Database.Cursor.execute(self, query)
query = self.convert_query(query)
print query,params#在这里添加了print
return Database.Cursor.execute(self, query, params)
再次migrate,并观察sql:
由于sql过多,只抓出insert的sql,如下:
INSERT INTO "auth_permission" ("name", "content_type_id", "codename")
SELECT ? AS "name", ? AS "content_type_id", ? AS "codename"
UNION ALL SELECT ?, ?, ?
UNION ALL SELECT ?, ?, ?
...
(
u'Can add tag', 7, u'add_tag',
u'Can change tag', 7, u'change_tag',
u'Can delete tag', 7, u'delete_tag',
...
)
即写表auth_permission ,django的权限表,可以参考这里。
经过反复的try发现,default_permissions只是取出 default_permissions[0],default_permissions[1],default_permissions[2]然后将其插入到数据表auth_permission里面。而且版本1.7.2的还有bug:
case 1. str类型赋值
default_permissions='abcde'
sql如下,以上代码为抽象基类中的meta类,对于子类(Tag,ContentType,Menu,Page)来说,只有最后一个Page起到作用了(id为10)
INSERT INTO "auth_permission" ("name", "content_type_id", "codename")
SELECT ? AS "name", ? AS "content_type_id", ? AS "codename" UNION ALL SELECT ?, ?, ? UNION A
LL SELECT ?, ?, ? UNION ALL SELECT ?, ?, ? UNION ALL SELECT ?, ?, ?
UNION ALL SELECT ?, ?, ? UNION ALL SELECT ?, ?, ? UNION ALL SELECT ?, ?, ? UNION ALL SELECT ?,
?, ? UNION ALL SELECT ?, ?, ? UNION ALL SELECT ?, ?, ? UNION ALL SELECT ?, ?, ?
UNION ALL SELECT ?, ?, ? UNION ALL SELECT ?, ?, ?
(u'Can add tag', 7, u'add_tag',
u'Can change tag', 7, u'change_tag',
u'Can delete tag', 7, u'delete_tag',
u'Can add content type', 8, u'add_contenttype',
u'Can change content type', 8, u'change_contenttype',
u'Can delete content type', 8, u'delete_contenttype',
u'Can add menu', 9, u'add_menu',
u'Can change menu', 9, u'change_menu',
u'Can delete menu', 9, u'delete_menu',
u'Can a page', 10, 'a_page',
u'Can b page', 10, 'b_page',
u'Can c page', 10, 'c_page',
u'Can d page', 10, 'd_page',
u'Can e page', 10, 'e_page')
case 2. tuple/list ,长度小于3
抽象基类default_permissions属性
default_permissions=('add', 'change')
生成的sql代码:
INSERT INTO "auth_permission" ("name", "content_type_id", "codename") SELECT ? AS "name", ? AS "content_type_id", ? AS "codename" UNION ALL SELECT ?, ?, ? UNION A
LL SELECT ?, ?, ? UNION ALL SELECT ?, ?, ? UNION ALL SELECT ?, ?, ? UNION ALL SELECT ?, ?, ? UNION ALL SELECT ?, ?, ? UNION ALL SELECT ?, ?, ? UNION ALL SELECT ?,
?, ? UNION ALL SELECT ?, ?, ? UNION ALL SELECT ?, ?, ?
(u'Can add tag', 7, u'add_tag',
u'Can change tag', 7, u'change_tag',
u'Can delete tag', 7, u'delete_tag',
u'Can add content type', 8, u'add_contenttype',
u'Can change content type', 8, u'change_contenttype',
u'Can delete content type', 8, u'delete_contenttype',
u'Can add menu', 9, u'add_menu',
u'Can change menu', 9, u'change_menu',
u'Can delete menu', 9, u'delete_menu',
u'Can add page', 10, 'add_page',
u'Can change page', 10,'change_page')
跟case 1 差不多,有作用,有bug。
结论:
往表auth_permissions里面插入记录而已。
鉴于只对子类中的最后一个模型起作用(包括permissions属性),因此不能作为公共属性。
django 1.7+ default_permissions的更多相关文章
- Django模型类Meta元数据详解
转自:https://my.oschina.net/liuyuantao/blog/751337 简介 使用内部的class Meta 定义模型的元数据,例如: from django.db impo ...
- django _meta方法
models.Book._meta.'concrete_model': <class 'books.models.Book'> models.Book._meta.'related_fke ...
- Django的Model上都有些什么
Django的Model上都有些什么 modelinfo= ['DoesNotExist', 'MultipleObjectsReturned', '__class__', '__delattr__' ...
- Django 模型和数据库 总结
模型和数据库 模型 首先我们在创建一个model的时候,这个类都是继承自 django.db.models.Model, 各种Model Field类型 AutoField,自动增长的IntegerF ...
- 模型的元数据Meta -- Django从入门到精通系列教程
该系列教程系个人原创,并完整发布在个人官网刘江的博客和教程 所有转载本文者,需在顶部显著位置注明原作者及www.liujiangblog.com官网地址. Python及Django学习QQ群:453 ...
- 【Django】模型层说明
[Django模型层] 之前大概介绍Django的文章居然写了两篇..这篇是重点关注了Django的模型层来进行学习. ■ 模型定义 众所周知,Django中的模型定义就是定义一个类,其基本结构是这样 ...
- Django 模型层
基本操作 1.meta类属性汇总 属性名 用法 举例代码 abstract 如果设置abstract=True则这个模式是一个抽象基类 db_table 定义model在数据库中的表名称,如果不定 ...
- 三 Django模型层之Meta
模型的Meta选项 本文阐述所有可用的元数据选项,你可以在模型的Meta类中设置他们 Meta选项 abstract 如果为True,就表示抽象基类 app_label 如果模型在INSTALLED_ ...
- django之ModelBase类及mezzanine的page link类
class ModelBase(type): """ Metaclass for all models. """ def __new__(c ...
随机推荐
- HDU 1010 Tempter of the Bone(DFS+奇偶剪枝)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1010 题目大意: 输入 n m t,生成 n*m 矩阵,矩阵元素由 ‘.’ 'S' 'D' 'X' 四 ...
- jquery实现图片预加载
使用jquery实现图片预加载提高页面加载速度和用户体,本就为大家详细分析jquery图片预加载的实现原理. 什么时候使用图片预加载? 如果页面使用了很多不是最初加载便可见的图片,有必要进行预加载: ...
- ecshop后台,listtable.js使用
1.先载入listtable.js 2.html代码 a. <a href="javascript:listTable.sort('goods_number'); "> ...
- ecshop 活动-》红包
按商品发放:可以给指定某个商品发红包(购买付款,卖家发货后,会自动给买家发送红包:不是买家在付款的时候就自动可以减少红包金额) 按订单金额发放:订单满xx后(卖家发货后,会自动给买家发放红包)
- Robot Framework--04 工作区
转自:http://blog.csdn.net/tulituqi/article/details/7592711 一:Edit 接着前面的来,重新打开我们的RIDE,你会发现之前最后加的Resourc ...
- HTML5 Web Form 新增属性和表单验证
<form>标签的基本属性 method属性:指定浏览器向服务器传送数据的方式,可选: action属性:设置服务器接受和处理表单数据的URL: enctype属性:制定表单数据在发送到服 ...
- union联合体使用详解
1.联合体联合体(union)与结构体(struct)有一些相似之处.但两者有本质上的不同.在结构体中,各成员有各自的内存空间, 一个结构变量的总长度是各成员长度之和.而在联合体中,各成员共享一段内存 ...
- Ftp软件
http://www.xlightftpd.com/cn/index.htm FileZilla Server官网:http://www.filezilla-project.org/
- linux的多媒体 播放 软件版权问题
linux下基本很多 跟多媒体 相关的软件, 都是有版权的, 都是 第三方软件, 都是closed-resource的 都有版权问题, 因此, 几乎所有的 linux的 发行版 都不会带有 多媒体软件 ...
- Unity3D
一.安装配置 1.下载页面:http://unity3d.com/get-unity 分个人版本和专业版,个人版免费,但少了很多功能(主要是渲染相关,具体请看官方说明), 专业版是每月 75$ 或一次 ...