I want to set up some parameters and initialize the Injector object, because I want to use a dependency injection and singletons in my Django app.
Usually I do that in the main.py of my app but with Django I don't see where the first entry point of the application is when it runs. Where shoud I initialize the injector and pass it my views and services?
I have a view like this:
from uuid import UUID
from django.shortcuts import render
from django.http.response import JsonResponse
from django.http.request import HttpRequest
from rest_framework import viewsets, status
from rest_framework.parsers import JSONParser
from rest_framework.response import Response
from Instruments.services import InstrumentsService
from rest_framework.decorators import api_view
from Instruments.services import InstrumentsService
from injector import singleton, inject
# Application views live here
@singleton
class InstrumentViewSet(viewsets.ModelViewSet):
@inject
def __init__(self, instrument_service: InstrumentsService, **kwargs):
self.instrument_service = instrument_service
super().__init__(**kwargs)
def list(self, request: HttpRequest):
data = {}
try:
data = self.instrument_service.get_instruments()
return JsonResponse(data, status=status.HTTP_200_OK, safe=False)
except Exception as exc:
return JsonResponse(
{"Status": f"Error: {exc}"},
status=status.HTTP_400_BAD_REQUEST,
safe=False,
)
def create(self, request):
instrument_data = JSONParser().parse(request)
data = {}
try:
data = self.instrument_service.add_instrument(instrument_data)
return JsonResponse(data, status=status.HTTP_201_CREATED, safe=False)
except Exception as exc:
return JsonResponse(data, status=status.HTTP_400_BAD_REQUEST, safe=False)
def retrieve(self, request, pk: UUID = None):
data = {}
try:
data = self.instrument_service.get_instrument_by_id(pk)
return JsonResponse(data, status=status.HTTP_200_OK, safe=False)
except Exception as exc:
return JsonResponse(
{"Status": f"Error: {exc}"},
status=status.HTTP_404_NOT_FOUND,
safe=False,
)
def update(self, request, pk: UUID = None):
instrument_data = JSONParser().parse(request)
data = {}
try:
data = self.instrument_service.update_instrument_by_id(pk, instrument_data)
return JsonResponse(data, status=status.HTTP_200_OK, safe=False)
except Exception as exc:
return JsonResponse(
{"Status": f"Error: {exc}"},
status=status.HTTP_404_NOT_FOUND,
safe=False,
)
def destroy(self, request, pk: UUID = None):
data = {}
try:
data = self.instrument_service.delete_instrument_by_id(pk)
return JsonResponse(data, status=status.HTTP_200_OK, safe=False)
except Exception as exc:
return JsonResponse(
{"Status": f"Error: {exc}"},
status=status.HTTP_404_NOT_FOUND,
safe=False,
)
and a service like this:
import uuid
from django.http.response import JsonResponse
from django.http.request import RAISE_ERROR, HttpRequest
from rest_framework.exceptions import NotFound, ValidationError
from rest_framework.parsers import JSONParser
from rest_framework import status
from Instruments.models import Instrument
from Instruments.serializers import InstrumentsSerializer
from django.shortcuts import get_object_or_404
from injector import inject, singleton
@singleton
class InstrumentsService:
@inject
def __init__(self, instruments: Instrument):
self.instruments = instruments.objects.all()
def get_instrument_by_id(self, id: uuid.UUID):
try:
instruments = get_object_or_404(self.instruments, pk=id)
serializer = InstrumentsSerializer(instruments)
except Instrument.DoesNotExist as exc:
raise NotFound(f"No items where found with the given id {id}")
return serializer.data
def update_instrument_by_id(self, id: uuid.UUID, instrument_data: dict):
try:
instruments = get_object_or_404(self.instruments, pk=id)
serializer = InstrumentsSerializer(instruments, data=instrument_data)
if serializer.is_valid():
serializer.save()
else:
raise ValidationError(
"The data provided for updating an instrument are not valid"
)
except Instrument.DoesNotExist as exc:
raise NotFound(f"No items where found with the given id {id}")
self.instruments = Instrument.objects.all()
return serializer.data
def delete_instrument_by_id(self, id: uuid.UUID):
try:
instruments = get_object_or_404(self.instruments, pk=id)
serializer = InstrumentsSerializer(instruments)
instruments.delete()
except Instrument.DoesNotExist as exc:
raise NotFound(f"No items where found with the given id {id}")
self.instruments = Instrument.objects.all()
return serializer.data
def get_instruments(self):
serializer = InstrumentsSerializer(self.instruments, many=True)
return serializer.data
def add_instrument(self, instrument_data: Instrument):
serializer = InstrumentsSerializer(data=instrument_data)
if serializer.is_valid():
serializer.save()
else:
raise ValidationError(
"The data provided for registering a new instrument are not valid"
)
self.instruments = Instrument.objects.all()
return serializer.data
where would someone inilialize the injector to create the dependencies?
CodePudding user response:
Maybe you can look at Django Applications
In you application folder, you probably have an apps.py
file:
from django.apps import AppConfig
class MyApp(AppConfig):
def ready(self):
# do stuff here
This is the entry point of your application.
Edit:
There is a project that already do that: django-injector
CodePudding user response:
OK I made the dependency injection work the problem was not the injector it was the fact that in the class InstrumentsService:
posted above I was trying to do :
def __init__(self, instruments: Instrument):
self.instruments = instruments.objects.all()
but the object manager is not accesible for Django object thourgh objects (clas instances) but directly through the class. SO if I correct the class InstrumentsService:
to this and also use this django-injector
module Django injector everything works:
import uuid
from django.http.response import JsonResponse
from django.http.request import RAISE_ERROR, HttpRequest
from rest_framework.exceptions import NotFound, ValidationError
from rest_framework.parsers import JSONParser
from rest_framework import status
from Instruments.models import Instrument
from Instruments.serializers import InstrumentsSerializer
from django.shortcuts import get_object_or_404
class InstrumentsService:
def __init__(self):
self.instruments = Instrument.objects.all()
def get_instrument_by_id(self, id: uuid.UUID):
try:
instruments = get_object_or_404(self.instruments, pk=id)
serializer = InstrumentsSerializer(instruments)
except Instrument.DoesNotExist as exc:
raise NotFound(f"No items where found with the given id {id}")
return serializer.data
def update_instrument_by_id(self, id: uuid.UUID, instrument_data: dict):
try:
instruments = get_object_or_404(self.instruments, pk=id)
serializer = InstrumentsSerializer(instruments, data=instrument_data)
if serializer.is_valid():
serializer.save()
else:
raise ValidationError(
"The data provided for updating an instrument are not valid"
)
except Instrument.DoesNotExist as exc:
raise NotFound(f"No items where found with the given id {id}")
self.instruments = Instrument.objects.all()
return serializer.data
def delete_instrument_by_id(self, id: uuid.UUID):
try:
instruments = get_object_or_404(self.instruments, pk=id)
serializer = InstrumentsSerializer(instruments)
instruments.delete()
except Instrument.DoesNotExist as exc:
raise NotFound(f"No items where found with the given id {id}")
self.instruments = Instrument.objects.all()
return serializer.data
def get_instruments(self):
serializer = InstrumentsSerializer(self.instruments, many=True)
return serializer.data
def add_instrument(self, instrument_data: Instrument):
serializer = InstrumentsSerializer(data=instrument_data)
if serializer.is_valid():
serializer.save()
else:
raise ValidationError(
"The data provided for registering a new instrument are not valid"
)
self.instruments = Instrument.objects.all()
return serializer.data