由于做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的更多相关文章

  1. Django模型类Meta元数据详解

    转自:https://my.oschina.net/liuyuantao/blog/751337 简介 使用内部的class Meta 定义模型的元数据,例如: from django.db impo ...

  2. django _meta方法

    models.Book._meta.'concrete_model': <class 'books.models.Book'> models.Book._meta.'related_fke ...

  3. Django的Model上都有些什么

    Django的Model上都有些什么 modelinfo= ['DoesNotExist', 'MultipleObjectsReturned', '__class__', '__delattr__' ...

  4. Django 模型和数据库 总结

    模型和数据库 模型 首先我们在创建一个model的时候,这个类都是继承自 django.db.models.Model, 各种Model Field类型 AutoField,自动增长的IntegerF ...

  5. 模型的元数据Meta -- Django从入门到精通系列教程

    该系列教程系个人原创,并完整发布在个人官网刘江的博客和教程 所有转载本文者,需在顶部显著位置注明原作者及www.liujiangblog.com官网地址. Python及Django学习QQ群:453 ...

  6. 【Django】模型层说明

    [Django模型层] 之前大概介绍Django的文章居然写了两篇..这篇是重点关注了Django的模型层来进行学习. ■ 模型定义 众所周知,Django中的模型定义就是定义一个类,其基本结构是这样 ...

  7. Django 模型层

    基本操作 1.meta类属性汇总 属性名 用法 举例代码 abstract 如果设置abstract=True则这个模式是一个抽象基类   db_table 定义model在数据库中的表名称,如果不定 ...

  8. 三 Django模型层之Meta

    模型的Meta选项 本文阐述所有可用的元数据选项,你可以在模型的Meta类中设置他们 Meta选项 abstract 如果为True,就表示抽象基类 app_label 如果模型在INSTALLED_ ...

  9. django之ModelBase类及mezzanine的page link类

    class ModelBase(type): """ Metaclass for all models. """ def __new__(c ...

随机推荐

  1. CSS样式优先级

    关于CSS样式优先级 一般情况下: [1位重要标志位] > [4位特殊性标志] > 声明先后顺序 !important > [ id > class > tag ] 使用 ...

  2. VC亲自教你写BP

    2015年5月24日下午,腾讯开放平台“创业ABC”沙龙在腾讯众创空间(上海)举行.活动以“创业融资实战——从计划书到如何估值到如何花钱”为主题,险峰华兴投资负责人徐建海先生现场分享<如何写BP ...

  3. Python操作 RabbitMQ、Redis、Memcache、SQLAlchemy

    Memcached Memcached 是一个高性能的分布式内存对象缓存系统,用于动态Web应用以减轻数据库负载.它通过在内存中缓存数据和对象来减少读取数据库的次数,从而提高动态.数据库驱动网站的速度 ...

  4. 将excel文件中的数据导入到mysql

    ·在你的表格中增加一列,利用excel的公式自动生成sql语句,具体方法如下:          1)增加一列(假设是D列)          2)在第一行的D列,就是D1中输入公式:=CONCATE ...

  5. 解决label点击事件触发两次问题

    问题描述: 通常,为了用户体验,我们点击单选框或者复选框后面文字,即可选中当前项.代码如下: <label> <input type="radio" name=& ...

  6. hdu4888 Redraw Beautiful Drawings 最大流+判环

    hdu4888 Redraw Beautiful Drawings Time Limit: 3000/1500 MS (Java/Others)    Memory Limit: 65536/6553 ...

  7. Mastering Web Application Development with AngularJS 读书笔记(二)

    第一章笔记 (二) 一.scopes的层级和事件系统(the eventing system) 在层级中管理的scopes可以被用做事件总线.AngularJS 允许我们去传播已经命名的事件用一种有效 ...

  8. Tomcat 6 --- 你很少使用的安全管理SecurityManager

    试想一下,如果你的JSP页面中包含一句代码“System.exit(1);”,你的web应用访问到该JSP时,会发生什么? 一般使用tomcat可能都没有注意到这个问题,本篇主要讲述tomcat 6中 ...

  9. iOS 8 牛刀小试

    iOS 8 牛刀小试 1.UIWindow的bounds发生变化(Window本身发生了旋转) iOS 7之前Window的bounds不会随着方向而变化,但是到了iOS 8以后,随着设备方向的旋转, ...

  10. POJ 2054 Color a Tree

    贪心....                    Color a Tree Time Limit: 1000MS   Memory Limit: 30000K Total Submissions:  ...