使用Django Rest框架在网址中过滤列表以获取分层数据

时间:2018-10-04 10:34:32

标签: django django-rest-framework

Django Rest Framework中的视图集使我的代码保持整洁:我可以定义一个模型,然后定义一个视图集。

但是,我如何最好地处理在另一个模型下分层的模型?例如:我有一个Project,其中有许多File,并且需要此API:

  1. GET /api/files:获取所有项目中的所有文件
  2. GET /api/files/:id:详细说明特定文件
  3. GET /api/projects/:id/files:列出项目中的所有文件

以下代码几乎起作用,除了3.的URL以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

我研究了一些解决方案,例如使用多个视图集或视图或定制包编写定制路由器。但是令我惊讶的是,要在一个Viewset中使用现成的DRF并不容易。我错过了一个把戏吗?人们在这种情况下通常会做什么?

2 个答案:

答案 0 :(得分:0)

为此,您应该在2个不同的模型之间创建关系。在文件模型中,创建1个与项目具有外键关联的字段。

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

答案 1 :(得分:0)

我了解的是,您需要同时完成所有这三个操作,以简化代码。 使用mixins是实现api的好方法,但我认为我建议您使用ModelViewSet,以获取更多详细信息click here 这是您无需指定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);
   ....
   ....