Django rest framework- calling another class-based view

Multi tool use
Django rest framework- calling another class-based view
I have pored over several similar posts (and Calling a class-based view of an app from another app in same project seemed promising, but does not work), but some are older and none quite work for me. Here's my setup (using Django==2.0.6, djangorestframework==3.8.2)
I have a basic model (simplified here):
from django.db import models
class Resource(models.Model):
name = models.CharField(max_length=100, null=False)
I have a basic endpoint where I can list and create Resource
instances:
Resource
from rest_framework import generics, permissions
from myapp.models import Resource
from myapp.serializers import ResourceSerializer
class ListAndCreateResource(generics.ListCreateAPIView):
queryset = Resource.objects.all()
serializer_class = ResourceSerializer
permission_classes = (permissions.IsAuthenticated,)
(afaik, the details of the serializer are not relevant, so that is left out).
Anyway, in addition to that basic endpoint, I have another API endpoint which performs some actions, but also creates some Resource
objects in the process. Of course, I would like to make use of the functionality encapsulated in the ListAndCreateResource
class so I only have to maintain one place where Resource
s are created.
Resource
ListAndCreateResource
Resource
I have tried:
Attempt 1:
class SomeOtherView(generics.CreateAPIView):
def post(self, request, *args, **kwargs):
# ... some other functionality...
# ...
response = ListAndCreateResource().post(request, *args, **kwargs)
# ... more functionality...
return Response({'message': 'ok'})
Unfortunately, that does not work for me. In my trace, I get:
File "/home/projects/venv/lib/python3.5/site-packages/rest_framework/generics.py", line 111, in get_serializer
kwargs['context'] = self.get_serializer_context()
File "/home/projects/venv/lib/python3.5/site-packages/rest_framework/generics.py", line 137, in get_serializer_context
'request': self.request,
AttributeError: 'ListAndCreateResource' object has no attribute 'request'
Attempt 2:
This attempt tries to use the as_view
method which is part of all Django class-based views:
as_view
class SomeOtherView(generics.CreateAPIView):
def post(self, request, *args, **kwargs):
# ... some other functionality...
# ...
response = ListAndCreateResource.as_view()(request, *args, **kwargs)
# ... more functionality...
return Response({'message': 'ok'})
But that gives up with:
AssertionError: The `request` argument must be an instance of `django.http.HttpRequest`, not `rest_framework.request.Request`
So my question is...is there a straightforward way to do this? I can access the _request
attribute of the rest_framework.request.Request
object (which is of type django.http.HttpRequest
, but then I do not have any of the authentication details that are contained in the DRF Request
object (indeed, my ListAndCreateResource
returns a 403 if I use response = ListAndCreateResource().as_view()(request._request, *args, **kwargs)
in attempt #2 above).
_request
rest_framework.request.Request
django.http.HttpRequest
Request
ListAndCreateResource
response = ListAndCreateResource().as_view()(request._request, *args, **kwargs)
Thanks in advance!
rest_framework.mixins.CreateModelMixin.create
1 Answer
1
You can access the request
with self.request
in class based views.
request
self.request
I do know that much, but perhaps I misunderstand your answer. The issue (in attempt #2) is that
self.request
is of type rest_framework.request.Request
. In attempt #1, I am unable to create an instance of ListAndCreateResource
that has the request
attribute set. If I set it explicitly, I just get other missing attribute errors for the ListAndCreateResource
object I am creating.– blawney_dfci
Jul 3 at 2:31
self.request
rest_framework.request.Request
ListAndCreateResource
request
ListAndCreateResource
I read your question and answered another thing, maybe try reading this.
– Setti7
Jul 3 at 2:43
I can sort of see where you're going by linking that thread (gives some alternate approaches), but I was hoping there was a more direct way without having to resort to a bunch of overridden methods. Thanks anyway.
– blawney_dfci
Jul 3 at 2:58
By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.
I suppose one possible alternative would be to move the code performing validation and object creation (the code typically run in
rest_framework.mixins.CreateModelMixin.create
) to some other function (outside of both classes) and have both of those views use that function. That doesn't strike me as particularly elegant, and I'm surprised this has not come up before in other DRF-related SO threads.– blawney_dfci
Jul 3 at 3:03