Search code examples
django-rest-frameworkdjango-viewsdjango-urlsdjango-rest-viewsetsdjango-url-reverse

Django Rest Framework Routing: Reverse for 'orders' not found. 'orders' is not a valid view function or pattern name


I'm not quite sure I'm understanding how routing works in DRF. I went through the documentation but still haven't grasp the differences.

I've got the following view:

from django.shortcuts import render
from django.shortcuts import get_object_or_404

from rest_framework.viewsets import ViewSet
from rest_framework.response import Response


from .models import Order
from .serializer import OrderSerializer


class OrderAPIViewSet(ViewSet):

    def post(self, request):
        print(request)

and this is urls.py within my app:

from django.urls import include, path
from rest_framework import routers
from .views import OrderAPIViewSet


router = routers.DefaultRouter()
router.register(r'orders', OrderAPIViewSet, basename='order')
urlpatterns = router.urls

and this is the main urls.py:

from django.contrib import admin
from django.urls import path, include
from django.conf.urls.static import static
from django.conf import settings

urlpatterns = [
    path('admin/', admin.site.urls),
    path('', include('products.urls')),
    path('', include('orders.urls'))
] + static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)

but when I try to access the orders endpoint via a simple test:

ORDERS_URL = reverse('orders')


class PublicOrderApiTests(TestCase):
    """
    Test the public facing Order API
    """

    def setUp(self):
        self.client = APIClient()
    

    def test_sample(self):

        data = {
            "product_id": 1,
            "price": 5.80
        }

        res = self.client.post(ORDERS_URL, data)

        print(res)

I'm getting the following error:

django.urls.exceptions.NoReverseMatch: Reverse for 'orders' not found. 'orders' is not a valid view function or pattern name.

what am I doing wrong? the endpoint for products works just fine but not for orders.


Solution

  • Found the issue or issues in this case:

    1. In my test I had defined the wrong parameter to get the url, so instead of ORDERS_URL = reverse('orders') it needed to beORDERS_URL = reverse('order-list') . *-list is used for GET /orders/ and POST /orders/ while *-detail is for all other endpoints: PUT /orders/{id} GET /orders/{id} etc

    2. The method in my view was post but ViewSetwhich I'm inheriting from doesn't have that method, it has the create method instead, so I needed to rename my post to create