Python Django中有问题模型的自定义权限
我当前的项目涉及一个遗留代码库,它以有限的方式使用Django的模型<代码>同步数据库未被使用(即,该模型未由Django管理)。我需要基于权限限制对某些列的访问(即,查看所有列的权限将显示所有列,而没有权限将用户限制为几个基本列)。此权限将应用于不同的表 我考虑这样做的方式是简单地使用SQL插入一个新的Python Django中有问题模型的自定义权限,python,django,authorization,Python,Django,Authorization,我当前的项目涉及一个遗留代码库,它以有限的方式使用Django的模型同步数据库未被使用(即,该模型未由Django管理)。我需要基于权限限制对某些列的访问(即,查看所有列的权限将显示所有列,而没有权限将用户限制为几个基本列)。此权限将应用于不同的表 我考虑这样做的方式是简单地使用SQL插入一个新的auth\u权限。然而,content\u type\u id列使这一点变得复杂:我的理解是,内容类型应用于一个模型,而这(正如我所说)需要应用于不同的表,并且我无法可靠地运行syncdb 是否有其他人
auth\u权限
。然而,content\u type\u id
列使这一点变得复杂:我的理解是,内容类型应用于一个模型,而这(正如我所说)需要应用于不同的表,并且我无法可靠地运行syncdb
是否有其他人按照这些思路实施了一些东西?您是使用了Django基础设施,还是为了安全起见使用了单独的表?您是在信号级别还是在使用模型的每个点上实施此操作的
谢谢 您始终可以围绕虚拟对象创建自定义权限,即:
class ColumnLevelPermissions(models.Model):
class Meta:
permissions = (
("can_view_column1", "Can view column 1"),
("can_view_column2", "Can view column 2"),
)
然后创建一个包装器来过滤数据库调用(您说您的模型不是由Django models.Model管理的):
唯一需要决定的是如何使用它。您可以从数据库中以dict()的形式创建对象,如果对象中的列出现在允许的列中,则只需按键过滤这些列即可。
这意味着您将从数据库中读取一些冗余数据。另一种解决方案是基于列修改“Select”查询,尽管这种方法不太安全
有关如何在代码中存储和读取对象的更多信息可能有助于定义最佳方法。您始终可以围绕虚拟对象创建自定义权限,即:
class ColumnLevelPermissions(models.Model):
class Meta:
permissions = (
("can_view_column1", "Can view column 1"),
("can_view_column2", "Can view column 2"),
)
然后创建一个包装器来过滤数据库调用(您说您的模型不是由Django models.Model管理的):
唯一需要决定的是如何使用它。您可以从数据库中以dict()的形式创建对象,如果对象中的列出现在允许的列中,则只需按键过滤这些列即可。
这意味着您将从数据库中读取一些冗余数据。另一种解决方案是基于列修改“Select”查询,尽管这种方法不太安全
关于如何在代码中存储和读取对象的更多信息可能有助于定义最佳方法。可能会对您有所帮助。我从来没用过,但我想你可以用
您可以为一组用户显示一些列或其他列,具体取决于请求该页面/模板的用户(使用一个简单的“if”模板标记)。这可能有点乏味,但它可以帮助你完成你正在寻找的东西
希望有帮助 也许能帮你。我从来没用过,但我想你可以用
您可以为一组用户显示一些列或其他列,具体取决于请求该页面/模板的用户(使用一个简单的“if”模板标记)。这可能有点乏味,但它可以帮助你完成你正在寻找的东西
希望有帮助 在我看来,您实际上是在寻找权限组。它们可以很容易地独立创建模型。用户组不需要包含任何实际权限 您可以检查用户是否在特定组中:
def user_in_group(user, group_name):
return user.groups.filter(name=group_name).count()
您可以这样使用它:
def my_view(request):
if user_in_group(request.user, 'view_all'):
# do the things
else:
# do the other things
# limit this view to 'view_all' users
@user_passes_test(lambda u: user_in_group(u, 'view_all'))
def my_other_view(request):
# and do some more things
我不知道你对我是什么意思
您是在信号电平上实现的,还是在
使用什么模型
显然,对于任何授权方法,您都需要在查看模型的任何位置插入检查,并插入逻辑以仅显示允许的列(如在模板中呈现列的子集)
为了确保没有访问错误的列,您可以编写代理类来限制对相应字段/列的访问,并使用代理实例而不是模型实例
class SomeModelProxy(object):
def __init__(self, model_instance, user):
self.instance = model_instance
self.user = user
def save(self, *args, **kwargs):
self.instance.save(*args, **kwargs)
# define other methods that are needed...
def __getattr__(self, name):
if not name in get_allowed_columns_for_user_somehow(self.user):
raise AttributeError
return getattr(self.instance, name)
def __setattr__(self, name, value):
if not name in get_allowed_columns_for_user_somehow(self.user):
raise AttributeError
setattr(self.instance, name, value)
在我看来,您实际上是在寻找权限组。它们可以很容易地独立创建模型。用户组不需要包含任何实际权限 您可以检查用户是否在特定组中:
def user_in_group(user, group_name):
return user.groups.filter(name=group_name).count()
您可以这样使用它:
def my_view(request):
if user_in_group(request.user, 'view_all'):
# do the things
else:
# do the other things
# limit this view to 'view_all' users
@user_passes_test(lambda u: user_in_group(u, 'view_all'))
def my_other_view(request):
# and do some more things
我不知道你对我是什么意思
您是在信号电平上实现的,还是在
使用什么模型
显然,对于任何授权方法,您都需要在查看模型的任何位置插入检查,并插入逻辑以仅显示允许的列(如在模板中呈现列的子集)
为了确保没有访问错误的列,您可以编写代理类来限制对相应字段/列的访问,并使用代理实例而不是模型实例
class SomeModelProxy(object):
def __init__(self, model_instance, user):
self.instance = model_instance
self.user = user
def save(self, *args, **kwargs):
self.instance.save(*args, **kwargs)
# define other methods that are needed...
def __getattr__(self, name):
if not name in get_allowed_columns_for_user_somehow(self.user):
raise AttributeError
return getattr(self.instance, name)
def __setattr__(self, name, value):
if not name in get_allowed_columns_for_user_somehow(self.user):
raise AttributeError
setattr(self.instance, name, value)
如果我理解正确,您需要显示任何表的所有/部分对象,具体取决于用户/使用者的某些属性。用户不能部分访问某些行,也不能完全访问其他行,这是一个要么全有要么全无的问题 这与ContentTypes框架无关,后者允许行级别的多态关系。您只需要过滤视图中暴露的字段 如果使用标准的用户/组类,则可以为每个表添加权限“see_complete_xxx”,并分配组,然后在视图中(作为api,可能会在字段上循环并将其转换为json/xml/任何内容)仅序列化组的允许字段 类似于:
from django.forms.models import model_to_dict
class MyModel(models.Model):
def serialize_full(self):
return model_to_dict(self)
def serialize_restricted(self):
return model_to_dict(self, self.low_level_access_fields)
def serialize_to_dict(self, user):
if self.user_can_view_all(user):
return self.serialize_full
else:
return self.serialize_restricted
@classmethod
def user_can_view_all(cls, user)
return user.has_perm('my_model.see_all')
@classmethod
def low_level_access_fields(cls)
return ["id", "name", "nickname"]
您可以将大部分代码提取到mixin中,并在需要时使用它。如果我理解正确,您需要根据用户/使用者的某些属性显示任何表的所有/部分对象。用户不能部分访问某些行,也不能完全访问其他行,这是一个要么全有要么全无的问题 这与ContentTypes框架无关,后者允许行级别的多态关系。你只需要过滤e