Хобрук: Ваш путь к мастерству в программировании

django-guardian и django-rest-framework

Я хотел бы управлять разрешением своих объектов с помощью django-guardian в спокойном проекте (используя django-rest-framework).

Что я хотел бы:

  • Разрешить подключенному пользователю создавать объект, только если у него есть разрешение «add_modelname».
  • Когда подключенный пользователь создает объект, установите разрешения «delete_modelname» и «change_modelname».
  • Разрешить подключенному пользователю редактировать объект, только если у него есть разрешение «change_modelobject».
  • Разрешить подключенному пользователю удалять объект, только если у него есть разрешение «delete_modelobject».

Я пытаюсь управлять этими случаями с помощью этого кода:

view.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)

разрешения.py

class ModelNamePermission(permissions.BasePermission):
    """
    Custom permission to only allow owners of an object to edit it.
    """

    def has_permission(self, request, view):
        if request.method in ['GET']:
            return request.user.has_perm('view_modelname')        
        if request.method in ['POST']:
            return request.user.has_perm('add_modelname')
        if request.method in ['PUT', 'PATCH']:
            return request.user.has_perm('change_modelname')
        if request.method in ['DELETE']:
            return request.user.has_perm('delete_modelname')
        return False

    def has_object_permission(self, request, view, obj):         
        if request.method in ['GET']:
            return request.user.has_perm('view_modelname', obj)        
        if request.method in ['POST']:
            return request.user.has_perm('add_modelname', obj)
        if request.method in ['PUT', 'PATCH']:
            return request.user.has_perm('change_modelname', obj)
        if request.method in ['DELETE']:
            return request.user.has_perm('delete_modelname', obj)
        return False

Первая проблема, с которой я сталкиваюсь, заключается в том, что у меня есть ошибка в этой строке:

assign_perm("change_modelname", request.user, self)

ошибка :

error: 'ModelNameViewSet' object has no attribute '_meta'

И я думаю, что остальная часть кода не будет работать, но, по крайней мере, вы можете видеть, что я хочу сделать.

Я не видел ни одного примера с этими специфическими случаями.

Изменить: Другое дело, что этот код:

request.user.has_perm('view_coachingrequest')

всегда возвращает истину. Но я никогда не устанавливал это разрешение для своего пользователя (может быть, поэтому пробовал только с правами администратора).


  • Я хотел бы сделать то же самое. Ты сделал это ? 20.03.2017

Ответы:


1

Метод create набора представлений вернет вам только что созданный экземпляр модели. Вы пытаетесь назначить разрешение самому объекту набора представлений. Код для вашего метода create должен быть следующим:

def create(self, request, *args, **kwargs):
    instance = super().create(request, *args, **kwargs)
    assign_perm("change_modelname", request.user, instance)
    assign_perm("delete_modelname", request.user, instance)
    return instance

Это создаст экземпляр модели, а затем назначит ему нужные разрешения перед его возвратом.

22.05.2017
  • Метод create в наборе представлений DRF возвращает объект ответа, а не экземпляр модели. Код здесь: github.com/encode/django -rest-framework/blob/ Вы думаете о методе create в сериализаторе? 25.05.2018
  • На самом деле это можно сделать либо в сериализаторе, либо в методе Perform_create() в наборе представлений (последний показан ответом здесь: stackoverflow.com/questions/41230236/ ). Так что выбор за вами, где хранить этот код. Для меня я думаю, что сделал бы это в сериализаторе (что может позволить вам написать более чистый код обработки ошибок, создав объект в том же месте, что и назначение разрешений) 27.05.2018
  • Новые материалы

    Решения DBA Metrix
    DBA Metrix Solutions предоставляет удаленного администратора базы данных (DBA), который несет ответственность за внедрение, обслуживание, настройку, восстановление базы данных, а также другие..

    Начало работы с Блум
    Обзор и Codelab для генерации текста с помощью Bloom Оглавление Что такое Блум? Некоторые предостережения Настройка среды Скачивание предварительно обученного токенизатора и модели..

    Создание кнопочного меню с использованием HTML, CSS и JavaScript
    Вы будете создавать кнопочное меню, которое имеет состояние наведения, а также позволяет вам выбирать кнопку при нажатии на нее. Финальный проект можно увидеть в этом Codepen . Шаг 1..

    Внедрите OAuth в свои веб-приложения для повышения безопасности
    OAuth — это широко распространенный стандарт авторизации, который позволяет приложениям получать доступ к ресурсам от имени пользователя, не раскрывая его пароль. Это позволяет пользователям..

    Классы в JavaScript
    class является образцом java Script Object. Конструкция «class» позволяет определять классы на основе прототипов с чистым, красивым синтаксисом. // define class Human class Human {..

    Как свинг-трейдеры могут использовать ИИ для больших выигрышей
    По мере того как все больше и больше профессиональных трейдеров и активных розничных трейдеров узнают о возможностях, которые предоставляет искусственный интеллект и машинное обучение для улучшения..

    Как построить любой стол
    Я разработчик программного обеспечения. Я люблю делать вещи и всегда любил. Для меня программирование всегда было способом создавать вещи, используя только компьютер и мое воображение...