Django每个用户模型的对象权限 [英] Django Per Object Permission for Your Own User Model

查看:204
本文介绍了Django每个用户模型的对象权限的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我已经实现了我自己的用户模型类,如下所示。请注意,它是自定义django的 auth.User 模型。我对这个对象的许可知识是新的,特别是在我的项目中需要的这个自定义的用户模型中。



在这种情况下,您可以举一个添加每个对象权限的示例吗?非常感谢。

  from django.contrib.auth.models import AbstractBaseUser,PermissionsMixin 

class CustomUser AbstractBaseUser,PermissionsMixin):
email = models.EmailField(max_length = 40,unique = True)
// ....其他字段被省略

class Article(models。模型)
title = models.CharField('title',max_length = 120)
body = models.TextField('body')
author = models.ForeignKey(CustomUser)

现在,对象权限发挥作用。每个用户可以创建/更新/删除/查看自己的文章对象,但只能查看他人的文章,而无需更新/删除它们。



从django文档,模型级许可不适用于此。如果文章给予模型级更新许可,那么所有用户都可以更新他人的文章。



所以,我发现了django-guardian。然而,这个自定义的CustomUser模型似乎并不希望,因为它非常依赖Django的 auth.User 模型!



https://django-guardian.readthedocs.org/en/v1.2/userguide/custom-user-model.html



更新:


  1. 我的例子是将AbstractBaseUser替代为AbstractUser;

  2. 这不适用于管理员,但仅适用于我的后端代码逻辑;

  3. 我没有在这里使用Django REST API,但如果REST API正确,请举个例子。 >


解决方案

即使使用标准的 auth.User 模型。但是基础是Django的 PermissionsMixin 定义了 has_perm 方法,它接受一个模型实例。 Django默认情况下不做任何事情,但您可以。



has_perm 方法有效地将艰苦的工作传递到注册认证后端。因此,您可以创建专门用于执行对象级权限检查的自定义身份验证后端。它不需要真正处理身份验证。它可以像基本类上的单一方法一样简单。所有你需要的东西如下(未经测试):

  class ObjectPermissionsBackend(object):

def has_perm(self,user_obj,perm,obj = None):
如果不是obj:
return False#不处理非对象权限

如果perm =='查看':
返回True#任何人都可以查看
elif obj.author_id == user_obj.pk:
return True
else:
return False

告诉Django使用 AUTHENTICATION_BACKENDS 设置使用您的自定义后端。在settings.py:

  AUTHENTICATION_BACKENDS =('django.contrib.auth.backends.ModelBackend','path.to.ObjectPermissionsBackend ')

然后,在你的代码中:

 如果user.has_perm('edit',article_instance):
#允许编辑

请参阅 https://docs.djangoproject.com/en/1.8/topics/auth/customizing/#custom-users-and-permissions https://docs.djangoproject.com/en/1.8/topics/auth/customizing/#specifying-authentication-backends


I have implemented my own User model class as follows. Note that is it NOT customizing django's auth.User model. I am new to this object permission knowledge and especially in this self-defined User model which is required in my project.

Could you give an example of adding per-object permission in this case? Much appreciated.

from django.contrib.auth.models import AbstractBaseUser, PermissionsMixin

class CustomUser(AbstractBaseUser, PermissionsMixin):
         email = models.EmailField(max_length=40, unique=True)
         //.... other fields are omitted

class Article(models.Model):
    title = models.CharField('title', max_length=120)
    body = models.TextField('body')
    author = models.ForeignKey(CustomUser)

Now, the object permission comes into play. Each user can create/update/delete/view their own article objects, but ONLY view others' articles without the permission to update/delete them.

From the django docs, the Model level permission does not apply here. If the Article is given model level update permission, then all users can update others' Article.

So, I found out the django-guardian. However, there seems to be no hope for this self-defined CustomUser model, as it relies heavily on Django's auth.User model!

https://django-guardian.readthedocs.org/en/v1.2/userguide/custom-user-model.html

UPDATE:

  1. My case is subclassing AbstractBaseUser instead of AbstractUser;
  2. This is not for the admin but only for my backend code logic;
  3. I am not using Django REST API here, but if REST API is proper, please give an example.

解决方案

Object-level permissions are not built into Django, even when using the standard auth.User model. But the foundation is there in that Django's PermissionsMixin defines the has_perm method, which accepts a model instance. Django does nothing with it by default, but you can.

The has_perm method effectively passes the hard work off onto the registered authentication backends. So you can create a custom authentication backend specifically for performing your object-level permission checks. It does not need to actually handle authentication. It can be as simple as a single method on a basic class. Something like the following (untested) is all you should need:

class ObjectPermissionsBackend(object):

    def has_perm(self, user_obj, perm, obj=None):
        if not obj:
            return False # not dealing with non-object permissions

        if perm == 'view':
            return True # anyone can view
        elif obj.author_id == user_obj.pk:
            return True
        else:
            return False

Tell Django to use your custom backend using the AUTHENTICATION_BACKENDS setting. In settings.py:

AUTHENTICATION_BACKENDS = ('django.contrib.auth.backends.ModelBackend', 'path.to.ObjectPermissionsBackend')

Then, in your code:

if user.has_perm('edit', article_instance):
    # allow editing

See https://docs.djangoproject.com/en/1.8/topics/auth/customizing/#custom-users-and-permissions and https://docs.djangoproject.com/en/1.8/topics/auth/customizing/#specifying-authentication-backends

这篇关于Django每个用户模型的对象权限的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆