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.
Found the issue or issues in this case:
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
The method in my view was post
but ViewSet
which I'm inheriting from doesn't have that method, it has the create
method instead, so I needed to rename my post
to create