Che*_*wie 75 django django-permissions
我想使用基于权限的系统来限制我的Django应用程序中的某些操作.这些操作不需要与特定模型相关(例如,访问应用程序中的部分,搜索......),因此我无法直接使用库存权限框架,因为Permission模型需要引用已安装的内容类型.
我可以编写自己的权限模型,但后来我必须重写Django权限中包含的所有好东西,例如:
permission_required装饰.User.has_perm 和相关的用户方法.perms模板变量.我已经检查了一些像django-authority和django-guardian这样的应用程序,但它们似乎通过允许每个对象的权限提供更多耦合到模型系统的权限.
有没有办法重新使用这个框架,而不必定义任何模型(除了User和Group)的项目?
Dmi*_*try 102
对于那些仍在搜索的人:
您可以创建没有数据库表的辅助模型.该模型可以为您的项目带来您需要的任何许可.无需处理ContentType或显式创建Permission对象.
from django.db import models
class RightsSupport(models.Model):
class Meta:
managed = False # No database table creation or deletion \
# operations will be performed for this model.
permissions = (
('customer_rights', 'Global customer rights'),
('vendor_rights', 'Global vendor rights'),
('any_rights', 'Global any rights'),
)
Run Code Online (Sandbox Code Playgroud)
之后manage.py migrate,你可以使用这些权限像任何其他.
# Decorator
@permission_required('app.customer_rights')
def my_search_view(request):
…
# Inside a view
def my_search_view(request):
request.user.has_perm('app.customer_rights')
# In a template
# The currently logged-in user’s permissions are stored in the template variable {{ perms }}
{% if perms.app.customer_rigths %}
<p>You can do any customer stuff</p>
{% endif %}
Run Code Online (Sandbox Code Playgroud)
Gon*_*alo 51
Django的Permission模型需要一个ContentType实例.
我认为一种方法是创建一个ContentType与任何模型无关的虚拟(app_label和model字段可以设置为任何字符串值).
如果你想要一切都干净又漂亮,你可以创建一个Permission 代理模型来处理虚拟的所有丑陋细节ContentType并创建"无模型"权限实例.您还可以添加自定义管理器,筛选出Permission与实际模型相关的所有实例.
Che*_*wie 49
根据Gonzalo的建议,我使用代理模型和自定义管理器来处理具有虚拟内容类型的"无模型"权限.
from django.db import models
from django.contrib.auth.models import Permission
from django.contrib.contenttypes.models import ContentType
class GlobalPermissionManager(models.Manager):
def get_query_set(self):
return super(GlobalPermissionManager, self).\
get_query_set().filter(content_type__name='global_permission')
class GlobalPermission(Permission):
"""A global permission, not attached to a model"""
objects = GlobalPermissionManager()
class Meta:
proxy = True
def save(self, *args, **kwargs):
ct, created = ContentType.objects.get_or_create(
name="global_permission", app_label=self._meta.app_label
)
self.content_type = ct
super(GlobalPermission, self).save(*args, **kwargs)
Run Code Online (Sandbox Code Playgroud)
修复了Chewie在Django 1.8中的回答,正如一些评论所要求的那样.
它在发行说明中说:
django.contrib.contenttypes.models.ContentType的名称字段已被迁移删除,并由属性替换.这意味着不再可以通过此字段查询或过滤ContentType.
因此,它是ContentType中引用的"名称",而不是在GlobalPermissions中使用.
当我修复它时,我得到以下内容:
from django.db import models
from django.contrib.auth.models import Permission
from django.contrib.contenttypes.models import ContentType
class GlobalPermissionManager(models.Manager):
def get_queryset(self):
return super(GlobalPermissionManager, self).\
get_queryset().filter(content_type__model='global_permission')
class GlobalPermission(Permission):
"""A global permission, not attached to a model"""
objects = GlobalPermissionManager()
class Meta:
proxy = True
verbose_name = "global_permission"
def save(self, *args, **kwargs):
ct, created = ContentType.objects.get_or_create(
model=self._meta.verbose_name, app_label=self._meta.app_label,
)
self.content_type = ct
super(GlobalPermission, self).save(*args)
Run Code Online (Sandbox Code Playgroud)
GlobalPermissionManager类未更改,但包含完整性.
这是替代解决方案。首先问问自己:为什么不创建一个真正存在于数据库中但从未被使用过的虚拟模型,除了持有权限?这不好,但我认为这是有效且直接的解决方案。
from django.db import models
class Permissions(models.Model):
can_search_blue_flower = 'my_app.can_search_blue_flower'
class Meta:
permissions = [
('can_search_blue_flower', 'Allowed to search for the blue flower'),
]
Run Code Online (Sandbox Code Playgroud)
上述解决方案的好处是,您可以Permissions.can_search_blue_flower在源代码中使用该变量,而不是使用文字字符串“my_app.can_search_blue_flower”。这意味着在 IDE 中更少的拼写错误和更多的自动完成。
| 归档时间: |
|
| 查看次数: |
19214 次 |
| 最近记录: |