I'm new to Python, Django and DRF but I've gone through all the tutorials needed to set up a basic REST server and for this example, we'll pretend that it only serves one thing: a list of customers. Additionally, I have installed django-simple-history
and registered my Customer
model with it.
This is the code that I've written so far and everything seems to work just fine.
api/urls.py
from django.urls import path, include
from rest_framework import routers
import api.views as views
router = routers.DefaultRouter(trailing_slash=False)
router.register('customers', views.CustomerView)
router.register('customerhistory', views.CustomerHistoryView)
urlpatterns = [
path('', include(router.urls)),
]
api/views.py
from rest_framework import viewsets
from retail.models.customers import Customer
class CustomerView(viewsets.ModelViewSet):
queryset = Customer.objects.all()
serializer_class = CustomerSerializer
filterset_fields = '__all__'
search_fields = ['name']
class CustomerHistoryView(viewsets.ModelViewSet):
queryset = Customer.history.all()
serializer_class = CustomerHistorySerializer
filterset_fields = '__all__'
api/serializers.py
from rest_framework import serializers
from retail.models.customers import Customer
class CustomerSerializer(serializers.ModelSerializer):
class Meta:
model = Customer
fields = '__all__'
class CustomerHistorySerializer(serializers.ModelSerializer):
class Meta:
model = Customer.history.model
fields = '__all__'
As it is, when I go to api/customerhistory/1
, it gives me a lovely list of all the history for customer 1.
Question
What I'd like to do is access the same list by going to api/customer/1/history
.
My Attempt So Far...
To do this, I'm removing the CustomerHistoryView
and adding an extra action to the CustomerView
class.
api/views.py
from rest_framework import viewsets
from rest_framework.decorators import action
from rest_framework.response import Response
from retail.models.customers import Customer
class CustomerView(viewsets.ModelViewSet):
queryset = Customer.objects.all()
serializer_class = CustomerSerializer
filterset_fields = '__all__'
search_fields = ['name']
@action(detail=True)
def history(self):
history = Customer.history.all()
serializer = CustomerHistorySerializer(history, many=True)
return Response(serializer.data)
This produces the following error:
Exception Type: TypeError at /api/customers/1/history
Exception Value: history() got multiple values for argument 'pk'
What am I doing wrong?
It looks like your history
method is missing parameters.
Here are the docs for extra actions on viewsets.
@action(detail=True)
def history(self, request, pk=None):
history = Customer.history.all()
# ...
Note the extra parameters request
and pk=None
to history
.