• 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	ommy.yuDesktopCaptainCaptain-mastercodesCaptainmanage.py", line 10, in <module>
        execute_from_command_line(sys.argv)
      File "C:Python27libsite-packagesdjango-1.7.2-py2.7.eggdjangocoremanagement\__init__.py", line 385, in execute_from_command_line
        utility.execute()
      File "C:Python27libsite-packagesdjango-1.7.2-py2.7.eggdjangocoremanagement\__init__.py", line 377, in execute
        self.fetch_command(subcommand).run_from_argv(self.argv)
      File "C:Python27libsite-packagesdjango-1.7.2-py2.7.eggdjangocoremanagementase.py", line 288, in run_from_argv
        self.execute(*args, **options.__dict__)
      File "C:Python27libsite-packagesdjango-1.7.2-py2.7.eggdjangocoremanagementase.py", line 338, in execute
        output = self.handle(*args, **options)
      File "C:Python27libsite-packagesdjango-1.7.2-py2.7.eggdjangocoremanagementcommandsmigrate.py", line 165, in handle
        emit_post_migrate_signal(created_models, self.verbosity, self.interactive, connection.alias)
      File "C:Python27libsite-packagesdjango-1.7.2-py2.7.eggdjangocoremanagementsql.py", line 268, in emit_post_migrate_signal
        using=db)
      File "C:Python27libsite-packagesdjango-1.7.2-py2.7.eggdjangodispatchdispatcher.py", line 198, in send
        response = receiver(signal=self, sender=sender, **named)
      File "C:Python27libsite-packagesdjango-1.7.2-py2.7.eggdjangocontribauthmanagement\__init__.py", line 114, in create_permissions
        Permission.objects.using(using).bulk_create(perms)
      File "C:Python27libsite-packagesdjango-1.7.2-py2.7.eggdjangodbmodelsquery.py", line 409, in bulk_create
        self._batched_insert(objs_without_pk, fields, batch_size)
      File "C:Python27libsite-packagesdjango-1.7.2-py2.7.eggdjangodbmodelsquery.py", line 938, in _batched_insert
        using=self.db)
      File "C:Python27libsite-packagesdjango-1.7.2-py2.7.eggdjangodbmodelsmanager.py", line 92, in manager_method
        return getattr(self.get_queryset(), name)(*args, **kwargs)
      File "C:Python27libsite-packagesdjango-1.7.2-py2.7.eggdjangodbmodelsquery.py", line 921, in _insert
        return query.get_compiler(using=using).execute_sql(return_id)
      File "C:Python27libsite-packagesdjango-1.7.2-py2.7.eggdjangodbmodelssqlcompiler.py", line 920, in execute_sql
        cursor.execute(sql, params)
      File "C:Python27libsite-packagesdjango-1.7.2-py2.7.eggdjangodbackendsutils.py", line 81, in execute
        return super(CursorDebugWrapper, self).execute(sql, params)
      File "C:Python27libsite-packagesdjango-1.7.2-py2.7.eggdjangodbackendsutils.py", line 65, in execute
        return self.cursor.execute(sql, params)
      File "C:Python27libsite-packagesdjango-1.7.2-py2.7.eggdjangodbutils.py", line 94, in __exit__
        six.reraise(dj_exc_type, dj_exc_value, traceback)
      File "C:Python27libsite-packagesdjango-1.7.2-py2.7.eggdjangodbackendsutils.py", line 65, in execute
        return self.cursor.execute(sql, params)
      File "C:Python27libsite-packagesdjango-1.7.2-py2.7.eggdjangodbackendssqlite3ase.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:Python27libsite-packagesdjango-1.7.2-py2.7.eggdjangodbackendssqlite3ase.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属性),因此不能作为公共属性。

  • 相关阅读:
    vmware 更换网络后不能上网
    IDEA “Cannot resolve symbol” 解决办法
    SpringBoot MyBatis druid数据库连接池
    解决分页插件ClassNotFoundException: org.springframework.boot.bind.RelaxedPropertyResolver
    纯CSS绘制不同角度的三角形
    原生js实现移动端点击、长按、左滑、右滑、上滑、下滑等事件模拟
    移动端下拉滚动刷新
    使用锚点定位不改变url同时平滑的滑动到锚点位置,不会生硬的直接到锚点位置
    简单的mock数据调试
    小程序textarea文本域字数控制---并显示已输入字数
  • 原文地址:https://www.cnblogs.com/Tommy-Yu/p/4202822.html
Copyright © 2020-2023  润新知