Reputation: 1858
I am kinda new to Django Rest Framework.
I have a views.py
that looks something like this:
class MyAPIView(APIView):
""" My API """
def get(self, request, path):
""" Handles GET calls """
def post(self, request, path):
""" Handles POST calls """
And I have a util class in my package like so:
class MyUtilClass: """ Helps out with stuff """
def some_method(self, path): print('I will now do things to the path: ', path)
Now, I would like to inject an instance of some other class that does some task that it's supposed to into my view. Something like this:
class MyAPIView(APIView):
""" My API """
_some_util_instance = None # How to inject this?
def __init__(self, util_instance):
self._some_util_instance = util_instance # Is this the right way?
def get(self, request, path):
""" Handles GET calls """
self._some_util_instance.some_method(path) # This is why I want this object injected.
def post(self, request, path):
""" Handles POST calls """
What is the best way to inject such an instance into my views class?
I could not find much about this in the documentation. I am familiar with using DI and IoC Containers. However, I am not sure how Django Rest Framework handles all of that.
Upvotes: 1
Views: 2094
Reputation: 1536
It's not ideal and I don't know if this would work for your case, but you can do something like this. Giving that this is your class
class MyAPIView(APIView):
""" My API """
_some_util_instance = None # How to inject this?
def get(self, request, path):
""" Handles GET calls """
self._some_util_instance.some_method(path) # This is why I want this object injected.
def post(self, request, path):
""" Handles POST calls """
In your urls.py you could inject the dependencies like this:
urlpatterns = [
path(
'your/cool/endpoint/',
MyAPIView.as_view(_some_util_instance=SomeUtilInstance()),
name='my-api-view'
),]
I haven't tried but I guess you could do the same in your tests, or just do some monkey patch there.
Upvotes: 0
Reputation: 9441
class MyAPIView(APIView):
""" My API """
_some_util_instance = MyUtilClass()
Or
class MyAPIView(APIView):
""" My API """
def __init__(self, *args, **kwargs):
self._some_util_instance = MyUtilClass()
super().__init__(self, *args, **kwargs)
Or
MyAPIView.as_view(
_some_util_instance=MyUtilClass()
)
class MyAPIView(APIView):
""" My API """
_some_util_instance = None
Or
don't use a class as a container for your utility functions, just define them as module-level functions. This is my preferred approach.
Or
Use static/class methods
class MyUtilClass:
""" Helps out with stuff """
@classmethod
def some_method(cls, path):
print('I will now do things to the path: ', path)
Then you can simply call MyUtilClass.some_method(path)
in the view without creating an instance of MyUtilityClass
Upvotes: 2