Django REST Framework: ограничить доступ к записям данных для пользователей, которые их создали

Я пытаюсь понять, как лучше всего управлять разрешениями на доступ к модели с помощью Django.

У меня есть таблица элементов, которые принадлежат пользователям, которые их создали. Все элементы управляются через RESTful API. При использовании этого API я хочу ограничить доступ к элементам, созданным данным пользователем.

Нужно ли мне создавать несколько таблиц или можно добиться того же с помощью одной таблицы? Если мне нужно использовать несколько таблиц, как мне соотнести запросы API с конкретной таблицей?


person Nikolay Derkach    schedule 11.12.2013    source источник


Ответы (4)


Хорошо, я нашел способ сделать это как через API, так и через администратора. Это в основном напоминает идею Роба.

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

class MyAdmin(admin.ModelAdmin):
    def save_model(self, request, obj, form, change):
        if getattr(obj, 'user', None) is None:
            obj.user = request.user
        obj.save()

admin.site.register(MyItem, MyAdmin)

Затем при доступе к моей модели я просто фильтрую по пользователю (который, кстати, является внешним ключом для django.contrib.auth.models.User):

MyItem.objects.filter(user=request.user)

Наконец, чтобы заставить его работать с Django REST Framework, мне нужно добавить пару методов в My custom ModelViewSet:

class MyItemViewSet(viewsets.ModelViewSet):
    model = MyItem
    serializer_class = MyItemSerializer

    def get_queryset(self):
        return MyItem.objects.filter(user=self.request.user)

    def pre_save(self, obj):
        obj.user = self.request.user

Я использовал документацию и (много) проб и ошибок, чтобы понять это.

person Nikolay Derkach    schedule 12.12.2013
comment
Это демонстрирует, насколько полезной была документация DRF. - person nehem; 22.03.2020

если вам нужны общие разрешения на уровне объекта, вы можете использовать бэкэнд разрешений, например django-guardian, здесь примеры интеграции с django-restframework

person krs    schedule 11.12.2013

У вас может быть поле created_by на ваших объектах. Затем сравните django user с этим. Дальнейшая помощь без конкретного примера немного сложна.

person Rob L    schedule 11.12.2013
comment
Не могли бы Вы уточнить? Например, как бы вы сгенерировали это поле и как именно вы бы сравнивали пользователя при отправке HTTP-запроса? - person Nikolay Derkach; 12.12.2013

Используя django-rest-framework и django-rest-auth, мне пришлось выполнить дополнительные шаги, как описано в ответе Лукаса Вейна на этот вопрос.

Вот то, что он предложил, и это сработало для меня.

Обязательно укажите в запросе токен авторизации:

curl -H "Authorization: Token 9944b09199c62bcf9418ad846dd0e4bbdfc6ee4b" <url>

Это ключевой момент, потому что в противном случае сервер не знает, кто является пользователем.

Добавьте это в определение вашего представления:

permission_classes = [permissions.IsAuthenticated, ]

Это важно, если запрос зависит от пользователя.

person Little Brain    schedule 14.01.2019