Reputation: 690
I used to have some massive files with decorated funtions called from urls.py
. This wasn't sustainable so they were split into controllers, with logic somewhere else (not relevant for this question). The controllers are subclassed from a main Controller
class to share frequent imports and other commonalities.
I can't get the decorator functions to work now, the closest I've gotten are
AssertionError: The `request` argument must be an instance of `django.http.HttpRequest`, not `api.controllers.FooController.FooController`.
and
AttributeError: 'functools.partial' object has no attribute '__name__'
Neither using a get()
with as_view()
nor a custom method work, as seen below.
I've tried @method_decorator(login_required)
etc. with no success.
My files (simplified) are below. Do not mind the method contents, this is just for demonstration.
api/urls.py
:
from django.urls import path
from api.controllers.FooController import FooController
urlpatterns = [
path("get_foo", FooController,as_view(), name="get_foo")
path("get_bar", FooController.foo_bar, name="get_bar")
]
api/controllers/Controller.py
:
from django.views import View
from rest_framework.authentication import SessionAuthentication, TokenAuthentication
from rest_framework.decorators import api_view, authentication_classes, permission_classes
from django.http import HttpResponse, JsonResponse, StreamingHttpResponse
from django.contrib.auth.decorators import login_required
from django.utils.decorators import method_decorator
class Controller(View):
def __init__(self):
# Set some variables
# define some methods
api/controllers/FooController.py
:
from api.controllers.Controller import *
class FooController(Controller):
method_decorator(api_view(["GET"]))
method_decorator(login_required)
method_decorator(authentication_classes((SessionAuthentication, TokenAuthentication,)))
method_decorator(permission_classes((IsAuthenticated,)))
def get(self, request):
if request.user.is_authenticated:
return HttpResponse(status=200)
else:
return HttpResponse(status=401)
method_decorator(api_view(["GET"]))
method_decorator(login_required)
method_decorator(authentication_classes((SessionAuthentication, TokenAuthentication,)))
method_decorator(permission_classes((IsAuthenticated,)))
def foo_bar(self, request):
if request.user.is_authenticated:
return JsonResponse({"data": "some data"}, status=200)
Thanks so much in advance if anyone can help me with this!
Upvotes: 0
Views: 206
Reputation: 28
In your urls.py
, use paths like so:
path("get_foo", FooController.as_view({"get":"get_foo"}), name="get_foo"),
Use Django's APIView in your base Controller.py
:
from rest_framework import viewsets
class Controller(viewsets.ViewSet):
def __init__(self):
# Code
Then start your FooController class in FooController.py
like so:
class FooController(Controller):
authentication_classes = [SessionAuthentication, TokenAuthentication]
permission_classes = [IsAuthenticated]
def get_foo(self, request):
Upvotes: 1