Отфильтрованный список в URL для иерархических данных с Django Rest Framework - PullRequest
0 голосов
/ 04 октября 2018

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

Однако, как мне лучше всего работать с моделями, которые иерархически подчиняются другой?Например: у меня есть Project, у которого много File с, и я хочу этот API:

  1. GET /api/files: получить все файлы во всех проектах
  2. GET /api/files/:id:детализировать конкретный файл
  3. GET /api/projects/:id/files: перечислить все файлы в проекте

Следующий код почти работает, за исключением того, что выходит URL для 3.as api/files/projects/:id:

class FileViewSet(
    mixins.ListModelMixin, mixins.RetrieveModelMixin, viewsets.GenericViewSet
):
    queryset = File.objects.all()
    serializer_class = FileSerializer

    @action(methods=["get"], url_path="projects/(?P<project_id>[^/.]+)", detail=False)
    def list_for_project(self, request, project_id):
        project = Project.objects.get(id=project_id)
        # ... list only Files for this Project

Я рассмотрел несколько решений, таких как написание пользовательских маршрутизаторов, использование более чем одного набора или представления или пользовательских пакетов;но я удивлен, что это не так просто сделать с DRF "из коробки" за один Viewset.Я пропускаю трюк?Что люди обычно делают в этом сценарии?

Ответы [ 2 ]

0 голосов
/ 04 октября 2018

Что я понял, так это то, что вам нужно упростить код, одновременно выполняя все эти три.Использование mixins - отличный способ реализовать API, но, на мой взгляд, я рекомендую вам использовать ModelViewSet, для более подробной информации нажмите здесь Это самый простой способ, в котором вам не нужно указыватьшаблоны URL, такие как projects/(?P<project_id>[^/.]+), приведу пример кода

views.py

from rest_framework import view sets
from django.shortcuts import render
from .models import ModelName
from .serializers import SerializerName

class TestAPIView(viewsets.ModelViewSet):
    queryset = ModelName.objects.all()
    serialiser_class = SerializerName

urls.py

import rest_framework import routers
from .views import TestAPIView


router = routers.DefaultRouter()
router.register('test',TestAPIView, base_name="api-test")
urlpatterns= router.urls  

Первые два будут правильно работать таким образом, а для третьего вы можете справиться с этим creating multiple model classes projects and files добавить отношение внешнего ключа между этими классами, например:

class ProjectModel(models.Model):
   ...
   ...

class FileModel(models.Model):
   project = models.ForeignKey(ProjectModel);
   ....
   ....
0 голосов
/ 04 октября 2018

Для этого вы должны создать связь между двумя разными моделями.В файле модель создайте 1 поле с привязкой внешнего ключа к проектам.

class File(models.Model):
    projects = models.ForeignKey(Projects)
...