由于做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. AppDelegate方法中文记录

    /// 在程序启动之后,重写自定义设置的位置 - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOption ...

  2. strace命令(收集整理,常看常新)

    starce的用途和参数:http://man.linuxde.net/strace(linux命令大全) strace命令是一个集诊断.调试.统计与一体 的工具,我们可以使用strace对应用的系统 ...

  3. Python之路【第九篇】堡垒机基础&数据库操作

    复习paramiko模块 Python的paramiko模块,是基于SSH用于连接远程服务器并执行相关操作. SSHClient #!/usr/bin/env python #-*- coding:u ...

  4. [Js/Jquery]jquery插件开发

    摘要 上篇文章简单学习了js自调用方法.今天就趁热打铁,学一学怎么编写一个jquery插件. JQuery 参考地址:http://www.cnblogs.com/playerlife/archive ...

  5. 要让div中的float不会自动显示到下一行来?

    使用 高度 + hidden: 要尝试 恰当的 高度, 设置合适的 div的 height: ... 要让 float的 "最直接的" "亲生的 " " ...

  6. socket编程报异常java.io.EOFException

    一个客户端连接服务器的小程序,服务器端可以正常读取客户端发来的数据 但是当客户端关闭时,服务端也关闭了,并且抛出如下的异常: java.io.EOFException at java.io.DataI ...

  7. Maven初级学习(二)Maven使用入门

    序,学习配置pom.xml,利用maven生成eclipes项目. 一.编写POM POM Project Obejct Model,项目对象模型. 编写pom.xml,新建文件夹hello-worl ...

  8. Jquery Md5加密解密

    首先需要调用md5解析的js文件.(右击-目标另存为方式下载) http://files.cnblogs.com/files/colinliu/md5.js 加密方法参考: <script ty ...

  9. 黄学长模拟day1 球的序列

    N个编号为1-n的球,每个球都有唯一的编号.这些球被排成两种序列,分别为A.B序列,现在需要重新寻找一个球的序列l,对于这个子序列l中任意的两个球,要求j,k(j<k),都要求满足lj在A中位置 ...

  10. ML_R kNN

    邻近算法 K最近邻(kNN,k-NearestNeighbor)分类算法是数据挖掘分类技术中最简单的方法之一.所谓K最近邻,就是k个最近的邻居的意思,说的是每个样本都可以用它最接近的k个邻居来代表. ...