I was trying to implement SOLID Principles. this time Dependency inversion in Python - Django

63 Views Asked by At

TypeError: SignInView.init() missing 1 required positional argument: 'api_response_factory'

I try to use abstract methods but it failed. I'm new about SOLID implementation and new in python too, can someone give me an advice or idea about how to deal with this kind of erros?

I have to add that this is my first time asking in stackoverflow

from abc import ABC, abstractmethod
from rest_framework.views import APIView
from django.http import JsonResponse
from rest_framework import status

class ApiResponseFactoryAbstract(ABC):
    @abstractmethod
    def success(self) -> str:
        pass

class ApiResponseFactory(ApiResponseFactoryAbstract):
    def success(self) -> str:
        print("Testing")
        return "Testing"

class SignInView(APIView):
    def __init__(self, api_response_factory: ApiResponseFactoryAbstract):
        self.api_response_factory = api_response_factory

    def post(self, request):
        data = self.api_response_factory.success()
        return JsonResponse(data=data, status=status.HTTP_200_OK)

This is app/urls.py:

from django.urls import path
from . import views

router_auth = [
    path("sign-in/", views.SignInView.as_view(), name="sign-in"),
]

1

There are 1 best solutions below

0
willeM_ Van Onsem On

This will not work: the .as_view() will for each request construct a new SignInView object, to handle the request. But it thus does not pass an object.

Luckely we can. Indeed, we can pass one in the initkwargs with:

from django.urls import path

from . import views

router_auth = [
    path(
        'sign-in/',
        views.SignInView.as_view(api_response_factory=ApiResponseFactory()),
        name='sign-in',
    ),
]

that being said, I don't see the need for this. It is probably easier to work with a mixin that provides with implementations for success messages, etc. It looks a bit like over-engineering.