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)

猜你喜欢

转载自www.cnblogs.com/zhangtq/p/10656176.html