django 1.7+ default_permissions

20790 단어 Permission
Caption을 하려면 권한 설계를 해야 하기 때문입니다.핵심적인 디자인을 할 때는 권한의 기초 디자인을 잘 해야 한다.django 1.7+ 이후djangodb.modes 새 기능defaultpermissions, 공식 문서에 대한 설명이 상세하지 않습니다.
스스로 탐색하기로 결정하고 코드를 일일이 분석하고 싶지 않아 버그를 도입하여 핵심 노선을 직접 관찰했다.
버그 메서드 도입:
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',

...

)

 
 
쓰기 테이블 authpermission,django의 권한표는 참고할 수 있습니다여기..
반복된try발견,defaultpermissions는default만 꺼냅니다permissions[0],default_permissions[1],default_permissions[2] 그리고 데이터 테이블에 삽입auth퍼미션에그리고 버전 1.7.2에는 버그가 있습니다.
case 1. str 형식 할당
default_permissions='abcde'


ql는 다음과 같다. 상기 코드는 추상적인 기본 클래스 중의 메타 클래스이고 하위 클래스(Tag,ContentType,Menu,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 미만
추상 기본 클래스defaultpermissions 속성
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')

 
 
 
케이스 1과 차이가 많지 않고 효과가 있고 버그가 있습니다.
 
결론:
테이블 authpermissions에 기록을 삽입했을 뿐입니다.
하위 클래스의 마지막 모델에만 작용하기 때문에 (permissions 속성 포함) 공공 속성으로 사용할 수 없습니다.

좋은 웹페이지 즐겨찾기