zoukankan      html  css  js  c++  java
  • django的objects级别的权限控制

    django自带的权限控制是model级别权限控制,并没有提供对Object级别的权限控制,而只是在架构上留了口子。所以想要进行更细小化颗粒的权限,必须自定义权限,但是对于以下简单的验证来说,自定义权限先得工作量胎发,这里提供django-guardian进行objects级别的权限控制。

    步骤如下:

     1.安装django-guardian

    pip install django-guardian

    2. INSTALLED_APPS变量中加入guardian:

    INSTALLED_APPS = ( # ... 'guardian', )

     3.然后加入到身份验证后端AUTHENTICATION_BACKENDS

    AUTHENTICATION_BACKENDS = (
    'django.contrib.auth.backends.ModelBackend', # Django默认
    'guardian.backends.ObjectPermissionBackend', # guardian
    ) 


    注意事项:

    当多数据库时,django的权限控制存在bug,指定数据库路由对于权限来说其实是失效的,此时django只会去找默认的用户数据库里找object对应的表,这样会导致该表不存在。

     File "/usr/lib/python2.7/site-packages/guardian/shortcuts.py", line 116, in assign_perm
        return model.objects.assign_perm(perm, user, obj)
      File "/usr/lib/python2.7/site-packages/guardian/managers.py", line 49, in assign_perm
        obj_perm, _ = self.get_or_create(**kwargs)
      File "/usr/local/lib/python2.7/site-packages/django/db/models/manager.py", line 85, in manager_method
        return getattr(self.get_queryset(), name)(*args, **kwargs)
      File "/usr/local/lib/python2.7/site-packages/django/db/models/query.py", line 466, in get_or_create
        return self._create_object_from_params(lookup, params)
      File "/usr/local/lib/python2.7/site-packages/django/db/models/query.py", line 498, in _create_object_from_params
        obj = self.create(**params)
      File "/usr/local/lib/python2.7/site-packages/django/db/models/query.py", line 394, in create
        obj.save(force_insert=True, using=self.db)
      File "/usr/lib/python2.7/site-packages/guardian/models.py", line 32, in save
        content_type = get_content_type(self.content_object)
      File "/usr/local/lib/python2.7/site-packages/django/contrib/contenttypes/fields.py", line 258, in __get__
        rel_obj = ct.get_object_for_this_type(pk=pk_val)
      File "/usr/local/lib/python2.7/site-packages/django/contrib/contenttypes/models.py", line 174, in get_object_for_this_type
        return self.model_class()._base_manager.using(self._state.db).get(**kwargs)
      File "/usr/local/lib/python2.7/site-packages/django/db/models/query.py", line 374, in get
        num = len(clone)
      File "/usr/local/lib/python2.7/site-packages/django/db/models/query.py", line 232, in __len__
        self._fetch_all()
      File "/usr/local/lib/python2.7/site-packages/django/db/models/query.py", line 1118, in _fetch_all
        self._result_cache = list(self._iterable_class(self))
      File "/usr/local/lib/python2.7/site-packages/django/db/models/query.py", line 53, in __iter__
        results = compiler.execute_sql(chunked_fetch=self.chunked_fetch)
      File "/usr/local/lib/python2.7/site-packages/django/db/models/sql/compiler.py", line 899, in execute_sql
        raise original_exception
    ProgrammingError: (1146, "Table 'userfeedback.ai_report' doesn't exist")

    解决方法:

    对报错回溯发现报错是在 

     File "/usr/local/lib/python2.7/site-packages/django/contrib/contenttypes/models.py", line 174, in get_object_for_this_type这里发生的。

        return self.model_class()._base_manager.using(self._state.db).get(**kwargs)

     此时进入/usr/local/lib/python2.7/site-packages/django/contrib/contenttypes/models.py的174行,发现调用using(self._state.db)只会调用的当前的默认连接,此时将

     return self.model_class()._base_manager.using(self._state.db).get(**kwargs)改为 return self.model_class()._base_manager.get(**kwargs),直接调用django的

    orm查询管理器即可解决问题。

    具体修改见下图标红的地方。

    def get_object_for_this_type(self, **kwargs):
            """
            Returns an object of this type for the keyword arguments given.
            Basically, this is a proxy around this object_type's get_object() model
            method. The ObjectNotExist exception, if thrown, will not be caught,
            so code that calls this method should catch it.
            """
            #return self.model_class()._base_manager.using(self._state.db).get(**kwargs)
            return self.model_class()._base_manager.get(**kwargs)
        def get_all_objects_for_this_type(self, **kwargs):
            """
            Returns all objects of this type for the keyword arguments given.
            """
            #return self.model_class()._base_manager.using(self._state.db).filter(**kwargs)
            return self.model_class()._base_manager.filter(**kwargs)
  • 相关阅读:
    人间故事馆话题:聊聊那些被骗经历,让其他人不再被骗
    路过的风景
    路过的风景
    上海最适合拍照的旅游地点
    Java EE (11)
    五、服务器端的局域网
    P1294 高手去散步 洛谷
    堆排序【模板】
    P3383 【模板】线性筛素数 洛谷
    P1516 青蛙的约会 洛谷
  • 原文地址:https://www.cnblogs.com/zhangtq/p/10656176.html
Copyright © 2011-2022 走看看