Я не думаю, что вы должны включать все это в одно представление.Я бы использовал два ModelViewSets и структурировал их URL, как показано ниже:
views.py
class JobViewSet(ModelViewSet):
serializer_class = JobSerializer
queryset = Job.objects.all()
class TaskViewSet(ModelViewSet):
serializer_class = TaskSerializer
queryset = Task.objects.all()
def get_queryset(self, request, *args, **kwargs):
# Override get_queryset to allow filtering by `job_id` url kwarg.
qs = self.queryset
if kwargs.get('job_id'):
job = Job.objects.get(pk=kwargs.get('job_id'))
qs = qs.filter(job=job)
return qs
urls.py
urlpatterns = [
url(
r'^api/jobs/$',
JobViewSet.as_view({'get': 'list', 'post': 'create'}
),
url(
r'^api/jobs/(?P<pk>\d+)/$',
JobViewSet.as_view({'get': 'retrieve', 'patch': 'update', 'patch': 'partial_update', 'delete': 'destroy'}
),
url(
r'^api/jobs/(?P<job_id>\d+)/tasks/$',
TaskViewSet.as_view({'get': 'list', 'post': 'create'}
),
url(
r'^api/jobs/(?P<job_id>\d+)/tasks/(?P<pk>\d+)/$',
TaskViewSet.as_view({'get': 'retrieve', 'patch': 'update', 'patch': 'partial_update', 'delete': 'destroy'}
),
]
Я избегал использования Rest FrameworkМаршрутизаторы, но они, по сути, генерируют маршруты, аналогичные этим для отдельных наборов запросов, а вложенные наборы запросов усложняются с помощью маршрутизаторов.Вы можете заметить, что ваши маршруты ожидают, что аргумент ключевого слова pk
для ViewSets получит один экземпляр объекта, это значение поиска по умолчанию для ModelViewSets.Как только мы вложим конечную точку /tasks/
ниже конечной точки /jobs/
, нам нужно изменить аргумент ключевого слова pk
на jobs_id
, чтобы представление не использовало его в качестве значения поиска по умолчанию для задач.jobs_id
используется в пользовательском методе get_queryset
для соответствующей фильтрации.