Nano Hash - криптовалюты, майнинг, программирование

Django Rest Framework: несколько веток API с различными наборами запросов/разрешениями

В моем приложении Django-Rest-Framework мне нужно разделить API на две ветви, например:

  • /api/public/...
  • /api/private/...

Рассмотрим модель Analysis вот так:

from django.db import models
from django.conf import settings

class Analysis(models.Model):
    user = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE)
    public = models.BooleanField(default=True)

То, что я хочу, это:

  • /api/public/analysis =› отфильтровать набор запросов с помощью Q(public=True)
  • /api/private/analysis =› отфильтровать набор запросов с помощью Q(user=request.user) | Q(public=False)

Аналогичный шаблон требуется в моделях 5+.

Я подумал о двух недоработанных решениях:

1. AbstractViewSet делится на PublicViewSet и PrivateViewSet

class AbstractAnalysisViewSet(viewsets.ReadOnlyModelViewSet):
    queryset = Analysis.objects.all()
    serializer_class = AnalysisSerializer
    ordering = [
        "-created_at",
    ]
    permission_classes = [IsAuthenticated,]

class PrivateAnalysisViewSet(AbstractAnalysisViewSet):
    def get_permissions(self):
        permissions = super(PrivateAnalysisViewSet, self).get_permissions()
        if self.action in ["retrieve"]:
            permissions.append(HasObjectPermission())
        return permissions

    def get_queryset(self):
        queryset = super(PrivateAnalysisViewSet, self).get_queryset()
        if self.action in ["list"]:
            auth_user = self.request.user
            query = Q(user=auth_user) | Q(public=False)
            queryset = queryset.filter(query)
        return queryset

class PublicAnalysisViewSet(AbstractAnalysisViewSet):
    def get_permissions(self):
        permissions = super(PublicAnalysisViewSet, self).get_permissions()
        if self.action in ["retrieve"]:
            permissions.append(IsPublicObjectPermission())
        return permissions

    def get_queryset(self):
        queryset = super(AnalysisViewSet, self).get_queryset()
        if self.action in ["list"]:
            query = Q(public=True)
            queryset = queryset.filter(query)
        return queryset

Это будет работать, но я действительно не хочу дублировать представления в несколько классов, потому что тогда мне также нужно зарегистрировать несколько наборов представлений с помощью DRF router. Как я уже сказал, я должен применить один и тот же шаблон в 5 моделях, а это означает, что 5 * 3 = 15 классов наборов представлений, которые трудно поддерживать с течением времени, и их число быстро увеличивается по мере увеличения размера моего приложения.

2. Определите private или public путем разбора self.request.path

class AnalysisViewSet(viewsets.ReadOnlyModelViewSet):
    queryset = Analysis.objects.all()
    serializer_class = AnalysisSerializer
    ordering = [
        "-created_at",
    ]
    permission_classes = [IsAuthenticated,]

    def get_permissions(self):
        permissions = super(PublicAnalysisViewSet, self).get_permissions()
        if self.action in ["retrieve"]:
            if "/private/" in self.request.path:
                permissions.append(HasObjectPermission())
            else:
                permissions.append(IsPublicObjectPermission())
        return permissions

Мне нравится этот подход, но я не могу понять, как зарегистрировать этот набор представлений в DRF router, чтобы он позволял использовать префикс /public/ или /private/.

Любые другие интересные идеи для решения этой проблемы приветствуются и высоко ценятся.


Ответы:


1

Я разобрался, как прописать путь с роутером DRF:

from django.urls import re_path, include
from rest_framework import routers
from .views import AnalysisViewSet

router = routers.DefaultRouter(trailing_slash=False)
router.register(r"analysis", AnalysisViewSet)

urlpatterns = [
    re_path(r"(public|private)/", include(router.urls)),
]

EDIT: для большей детализации и строгости:

urls.py

re_path(r"(?P<private_or_public_prefix>public|private)/", include(router.urls)),

просмотры.py

    def get_permissions(self):
        permissions = super(PublicAnalysisViewSet, self).get_permissions()
        if self.action in ["retrieve"]:
            matcher = self.request.resolver_match
            if matcher.kwargs["private_or_public_prefix"] == "private":
                permissions.append(HasObjectPermission())
            else:
                permissions.append(IsPublicObjectPermission())
        return permissions

12.05.2021
Новые материалы

Кластеризация: более глубокий взгляд
Кластеризация — это метод обучения без учителя, в котором мы пытаемся найти группы в наборе данных на основе некоторых известных или неизвестных свойств, которые могут существовать. Независимо от..

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

Частный метод Python: улучшение инкапсуляции и безопасности
Введение Python — универсальный и мощный язык программирования, известный своей простотой и удобством использования. Одной из ключевых особенностей, отличающих Python от других языков, является..

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

Работа с векторными символическими архитектурами, часть 4 (искусственный интеллект)
Hyperseed: неконтролируемое обучение с векторными символическими архитектурами (arXiv) Автор: Евгений Осипов , Сачин Кахавала , Диланта Хапутантри , Тимал Кемпития , Дасвин Де Сильва ,..

Понимание расстояния Вассерштейна: мощная метрика в машинном обучении
В обширной области машинного обучения часто возникает необходимость сравнивать и измерять различия между распределениями вероятностей. Традиционные метрики расстояния, такие как евклидово..

Обеспечение масштабируемости LLM: облачный анализ с помощью AWS Fargate и Copilot
В динамичной области искусственного интеллекта все большее распространение получают модели больших языков (LLM). Они жизненно важны для различных приложений, таких как интеллектуальные..