为什么 django rest 框架在创建对象时不检查对象权限?用户应该能够创建他们无法看到、更新或删除的对象是没有意义的(无论如何对我来说)。目前我子类化了一个视图集
class CheckCreatePermissionsViewSet(ModelViewSet):
def perform_create(self, serializer):
'''
Called by create before calling serializer.save()
'''
obj = serializer.save()
try:
self.check_object_permissions(obj)
except:
obj.delete()
raise
Run Code Online (Sandbox Code Playgroud)
为什么默认情况下不实现?这让我很头疼,我想不出它会像这样实施的单一原因。
我正在使用django-tastypie编写 API 。我有两个自定义权限问题,希望django-guardian能够解决。
我有两个用户组临床医生和患者。临床医生应该能够访问仅属于其患者的对象,并且患者应该只能访问他们自己创建的对象。
我的代码如下:
class UserResource(ModelResource):
class Meta:
queryset = User.objects.all()
resource_name = 'auth/user'
excludes = ['email', 'password', 'is_superuser']
class BlogPostResource(ModelResource):
author = fields.ToOneField(UserResource, 'author', full=True)
class Meta:
queryset = BlogPost.objects.all()
resource_name = 'posts'
allowed_methods = ["get", "post"]
# Add it here.
authentication = BasicAuthentication()
authorization = DjangoAuthorization()
filtering = {
'author': ALL_WITH_RELATIONS,
}
Run Code Online (Sandbox Code Playgroud)
我如何使用权限来限制对此的访问BlogPostResource?
我有两个模型:
class ContactGroup(models.Model):
name = models.CharField(max_length=40)
class Meta:
permissions=(('view_group_contacts', 'View contacts from group'))
class Contact(models.Model):
name = models.CharField(max_length=40)
group = models.ForeignKey(ContactGroup)
class Meta:
permissions=(('view_contact', 'View contact'))
Run Code Online (Sandbox Code Playgroud)
例如,当我在执行`get_objects_for_user(User, 'appname.view_contact) 但仍然保留更改单个联系人权限的选项时,如何让 django 监护人考虑 ContactGroup 权限?(不排除,仅授予查看单个联系人的权限当用户没有整个组的权限时)
我能够设置django-guardian和我的django-rest-framework项目作为drf文档中的示例,但我没有实现我想要的行为.有人可以指出,如果我做错了什么或者我想做什么都不能用guardian?
建立
settings.py
INSTALLED_APPS = (
...
'guardian',
'simple',
)
AUTHENTICATION_BACKENDS = (
'django.contrib.auth.backends.ModelBackend',
'guardian.backends.ObjectPermissionBackend',
)
'DEFAULT_PERMISSION_CLASSES': (
'infrastructure.permissions.DjangoObjectPermissions',
)
Run Code Online (Sandbox Code Playgroud)
infrastructure.permissions.py
from rest_framework import permissions
class DjangoObjectPermissions(permissions.DjangoObjectPermissions):
"""
Similar to `DjangoObjectPermissions`, but adding 'view' permissions.
"""
perms_map = {
'GET': ['%(app_label)s.view_%(model_name)s'],
'OPTIONS': ['%(app_label)s.view_%(model_name)s'],
'HEAD': ['%(app_label)s.view_%(model_name)s'],
'POST': ['%(app_label)s.add_%(model_name)s'],
'PUT': ['%(app_label)s.change_%(model_name)s'],
'PATCH': ['%(app_label)s.change_%(model_name)s'],
'DELETE': ['%(app_label)s.delete_%(model_name)s'],
}
Run Code Online (Sandbox Code Playgroud)
models.py
class Event(models.Model):
name = models.CharField(max_length=255)
min_age = models.IntegerField()
def __str__(self):
return self.name
class Meta:
permissions …Run Code Online (Sandbox Code Playgroud) 我正在使用 django-guardian 在 Django 项目中实现每个对象的权限。我遇到了一个问题,注册用户无法查看匿名用户可以查看的对象。我曾想过,如果匿名用户有权限,那么注册用户应该有相同的权限(我无法想象我的网站的一部分,我希望匿名用户能够做某事而注册用户不能做某事)。
from core.models import MyObject
from django.contrib.auth.models import User
from guardian.shortcuts import
from guardian.utils import get_anonymous_user
m = MyObject.objects.get(id=1)
u = User.objects.get(username="MyUser")
anon = get_anonymous_user()
anon.has_perm('view_object', m)
# ^ Prints True
u.has_perm('view_object', m)
# ^ Prints False
Run Code Online (Sandbox Code Playgroud)
在我的项目中,我有一些可以是“公共”或“私有”的对象。当用户将对象标记为“公共”时,我向匿名用户授予“view_object”权限。我的视图使用 进行保护PermissionRequiredMixin,如下所示:
class MyObjectDetailsView(PermissionRequiredMixin, DetailView):
model = MyObject
permission_required = 'view_object'
Run Code Online (Sandbox Code Playgroud)
Django Guardian 是否提供某种方式为注册用户提供与匿名用户相同的权限?或者,如果用户没有权限但匿名用户有权限,也许有某种方法可以对 PermissionRequiredMixin 进行子类化以允许执行该操作?
我希望能够使用创建每个对象的权限django-guardian.
但我想添加一层围绕这些权限的逻辑.例如,如果某人拥有edit_booka Book的权限,那么他们Pages在该书中编辑的权限应该是隐含的.该rules包装似乎理想.
我想在一个安静的项目中使用 django-guardian 管理我的对象权限(使用 django-rest-framework)。
我想要什么:
我正在尝试使用以下代码管理这些案例:
查看.py
class ModelNameViewSet(viewsets.ModelViewSet):
"""
This viewset automatically provides `list`, `create`, `retrieve`,
`update` and `destroy` actions.
Additionally we also provide an extra `highlight` action.
"""
queryset = ModelName.objects.all()
serializer_class = ModelNameSerializer
permission_classes = (permissions.IsAuthenticatedOrReadOnly, ModelNamePermission)
def create(self, request, *args, **kwargs):
assign_perm("change_modelname", request.user, self)
assign_perm("delete_modelname", request.user, self)
return super().create(request, *args, **kwargs)
Run Code Online (Sandbox Code Playgroud)
权限.py
class ModelNamePermission(permissions.BasePermission):
"""
Custom permission to only allow owners of an object to edit it.
"""
def has_permission(self, request, view): …Run Code Online (Sandbox Code Playgroud) 我正在尝试为用户提供一个接口,以便在数据库上编写自定义查询.我需要确保他们只能查询他们被允许的记录.为此,我决定使用django-guardian应用基于行的访问控制.
这是我的模式的样子
class BaseClass(models.Model):
somefield = models.TextField()
class Meta:
permissions = (
('view_record', 'View record'),
)
class ClassA(BaseClass):
# some other fields here
classb = models.ForeignKey(ClassB)
class ClassB(BaseClass):
# some fields here
classc = models.ForeignKey(ClassC)
class ClassC(BaseClass):
# some fields here
Run Code Online (Sandbox Code Playgroud)
我希望能够使用get_objects_for_group如下:
>>> group = Group.objects.create('some group')
>>> class_c = ClassC.objects.create('ClassC')
>>> class_b = ClassB.objects.create('ClassB', classc=class_c)
>>> class_a = ClassA.objects.create('ClassA', classb=class_b)
>>> assign_perm('view_record', group, class_c)
>>> assign_perm('view_record', group, class_b)
>>> assign_perm('view_record', group, class_a)
>>> get_objects_for_group(group, 'view_record') …Run Code Online (Sandbox Code Playgroud) 要将一些内容添加到模型的 Django 管理视图中,我想覆盖change_form.html模板。根据文档,我需要change_form.html在文件夹中创建一个文件/project-path/templates/admin/appname/modelname/。当然,我需要确保该路径在TEMPLATE_DIRS. 这样的文件可能如下所示:
{% extends "admin/change_form.html" %}
{% load i18n %}
{% block after_field_sets %}
SOME CONTENT
{% endblock %}
Run Code Online (Sandbox Code Playgroud)
但是,我使用django-guardian来获得对象权限。这个 Django 应用程序也覆盖change_form.html(它工作正常——相关源似乎在这里),但 Django 没有选择我的模板扩展文件(即上面示例中的“一些内容”没有显示)。该块/件我要重写是不相同的那些Django的监护人覆盖,最终我想有增加的change_form.htmlDjango的guardion的和我的模板。
我在这里做错了什么?是否有可能让多个应用程序覆盖管理模板?
如果感兴趣,这是我的TEMPLATE_LOADERS设置:
TEMPLATE_LOADERS = (
'django.template.loaders.filesystem.Loader',
'django.template.loaders.app_directories.Loader'
)
Run Code Online (Sandbox Code Playgroud)
此外,django-guardian 是INSTALLED_APPS数组中的最后一个应用程序。
我曾经Django Guardian拥有对象级权限和全局权限。有些用户拥有具有全局权限的组,有些则具有对象级权限。这样,我似乎需要修改PermissionRequiredMixin以检查对象级权限。
views.py
class MainPageView(PermissionRequiredMixin, TemplateView):
permission_required = "app.view_mainpage"
template_name = "web/mainpage.html"
Run Code Online (Sandbox Code Playgroud)
如果用户具有全局权限,则此方法有效,但如果用户位于具有对象级权限的组下,则无效。使用监护人,要检查对象级权限,还必须传递对象实例。
例子:
self.request.user.has_perm('view_mainpage', obj)
Run Code Online (Sandbox Code Playgroud)
然后PermissionRequiredMixin,检查就这样进行,self.request.user.has_perms(perms)
那么,如果用户有一个具有view_mainpage特定对象权限的组,我该如何检查它呢?顺便说一句,我的所有权限都是一样的content_type。我有什么办法可以执行这个吗?PermissionRequiredMixin就像如果用户位于对象级组下以及None用户位于全局组下时我必须将对象实例传递给一样。
django-guardian ×10
django ×8
python ×6
permissions ×3
django-admin ×1
postgresql ×1
tastypie ×1