djangodjango-rest-frameworkdjango-oscar

Modifying oscarapi to show some endpoints as public from admin endpoints


What I am trying to achieve is to customize the oscarapi to expose the partner api to be public api instead of just for admin

I have followed the docs on how to customize the api and also did as suggested by Jamie Marshall in Extending django-oscarapi API ROOT to custom API class

So far I am able to overwrite the root.py file but failing to get oscar see the new urls.py file.

My work so far is as follows

  1. I created a api_customization/views/partner.py file
  2. I created a api_customization/views/root.py file
  3. I tried to extend the urls.py file by creating a api_customization/urls.py file

However, I'm getting the following error

  Traceback (most recent call last):
    File "/usr/local/lib/python3.7/site-packages/django/core/handlers/exception.py", line 47, in inner response = get_response(request)
    File "/usr/local/lib/python3.7/site-packages/django/core/handlers/base.py", line 181, in _get_response response = wrapped_callback(request, *callback_args, **callback_kwargs)
    File "/usr/local/lib/python3.7/contextlib.py", line 74, in inner return func(*args, **kwds)
    File "/usr/local/lib/python3.7/site-packages/django/views/decorators/csrf.py", line 54, in wrapped_view return view_func(*args, **kwargs)
    File "/usr/local/lib/python3.7/site-packages/django/views/generic/base.py", line 70, in view return self.dispatch(request, *args, **kwargs)
    File "/usr/local/lib/python3.7/site-packages/rest_framework/views.py", line 509, in dispatch response = self.handle_exception(exc)
    File "/usr/local/lib/python3.7/site-packages/rest_framework/views.py", line 469, in handle_exception self.raise_uncaught_exception(exc)
    File "/usr/local/lib/python3.7/site-packages/rest_framework/views.py", line 480, in raise_uncaught_exception raise exc
    File "/usr/local/lib/python3.7/site-packages/rest_framework/views.py", line 506, in dispatch response = handler(request, *args, **kwargs)
    File "/usr/local/lib/python3.7/site-packages/rest_framework/decorators.py", line 50, in handler return func(*args, **kwargs)
    File "/code/.../forked_apps/api_customization/views/root.py", line 52, in api_root apis = PUBLIC_APIS(request, format)
    File "/code/.../forked_apps/api_customization/views/root.py", line 29, in PUBLIC_APIS ("partners", reverse("partner-list", request=r, format=f)),
    File "/usr/local/lib/python3.7/site-packages/rest_framework/reverse.py", line 47, in reverse url = _reverse(viewname, args, kwargs, request, format, **extra)
    File "/usr/local/lib/python3.7/site-packages/rest_framework/reverse.py", line 60, in _reverse url = django_reverse(viewname, args=args, kwargs=kwargs, **extra)
    File "/usr/local/lib/python3.7/site-packages/django/urls/base.py", line 87, in reverse return iri_to_uri(resolver._reverse_with_prefix(view, prefix, *args, **kwargs))
    File "/usr/local/lib/python3.7/site-packages/django/urls/resolvers.py", line 685, in _reverse_with_prefix raise NoReverseMatch(msg)
  django.urls.exceptions.NoReverseMatch: Reverse for 'partner-list' not found. 'partner-list' is not a valid view function or pattern name.
  [09/Jul/2021 21:18:13] "GET /api/ HTTP/1.1" 500 136185

views/partner.py

from oscarapi.utils.loading import get_api_class
from oscar.core.loading import get_model
from rest_framework import generics

PartnerSerializer = get_api_class("serializers.product", "PartnerSerializer")
Partner = get_model("partner", "Partner")

class PublicPartnerList(generics.ListCreateAPIView):
    queryset = Partner.objects.all()
    serializer_class = PartnerSerializer

urls.py

from django.urls import path
from rest_framework.urlpatterns import format_suffix_patterns
from oscarapi.utils.loading import get_api_class
from oscarapi import urls

PublicPartnerList = get_api_class("views.partner", "PublicPartnerList")

urls.urlpatterns += [
    path("partners1/", PublicPartnerList.as_view(), name="partner-list"),
]

urls.urlpatterns += format_suffix_patterns(urls.urlpatterns)

views/root.py

import collections

from django.conf import settings

from rest_framework.decorators import api_view
from rest_framework.response import Response
from rest_framework.reverse import reverse


__all__ = ("api_root",)


def PUBLIC_APIS(r, f):
    return [
        # other urls .......
        ("partners", reverse("partner-list", request=r, format=f)),
    ]

# remaining file content ......

I need a direction or a hint on how to achieve this Any help is appreciated


Solution

  • I found a solution to this and might be helpful form someone

    I had to do the same steps done for root.py file to get my app recognise the custom urls.py file

    So what I did

    1. copy the content of urls.py
    2. modify the file to suit my needs
    3. update my app urls.py file to point to the custom urls.py file of the api
        //So from this
        path("api/", include("oscarapi.urls")),
        //To this
        path("api/", include("APP_NAME.forked_apps.api_customization.urls")),