Django REST Framework: ограничить доступ к записям данных созданным ими пользователям
Я пытаюсь выяснить, как лучше всего управлять разрешениями на доступ к моделям с помощью Django.
У меня есть таблица предметов, которые принадлежат созданным ими пользователям. Все элементы управляются через RESTful API. При использовании этого API я хочу ограничить доступ к элементам, созданным данным пользователем.
Нужно ли создавать несколько таблиц или это можно сделать с помощью одной таблицы? Если мне нужно использовать несколько таблиц, как мне соотнести запросы API с определенной таблицей?
3 ответа
Хорошо, я нашел способ сделать это как через 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, мне нужно добавить пару методов в Мой пользовательский 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
Я использовал документацию и (много) проб и ошибок, чтобы понять это.
Вы могли бы иметь created_by
поле на ваших объектах. Тогда сравните Джанго user
к этому. Это немного сложная помощь дальше без конкретного примера.
Если вам нужны общие разрешения на уровне объекта, вы можете использовать бэкэнд разрешений, такой как django-guardian, вот примеры для интеграции с django-restframework
Используя django-rest-framework и django-rest-auth, мне пришлось выполнить дополнительные шаги, как описано в ответе Лукаса Вейна на этот вопрос.
Вот что он предложил, чтобы это сработало для меня.
Не забудьте включить токен авторизации в запрос:
curl -H "Authorization: Token 9944b09199c62bcf9418ad846dd0e4bbdfc6ee4b" <url>
Это ключ, потому что иначе сервер не знает, кто пользователь.
Добавьте это к определению вашего набора:
permission_classes = [permissions.IsAuthenticated, ]
Это важно, если запрос зависит от пользователя.