Retrieve an Object using Multiple Parameters inside of an Url in Django-Rest-Framework

Question:

How to retrieve an object using multiple parameters in url? Example : ‘customer/3/order/1/’ or ‘customer/<int:customer_pk>/order/<int:pk>/’

Using shell i’m able to get the object like this but i can’t seem to do it from the views.

>>> from temp.models import Customer, Order
>>> from temp.serializers import CustomerSerializer, OrderSerializer
>>> q = Order.objects.filter(customer=1).get(order_number=2)
>>> q.order_name
'fruit'

views.py

from rest_framework import generics
from rest_framework.views import APIView

from .models import *
from .serializers import *

class OrderDetailView(generics.RetrieveDestroyAPIView):
    serializer_class = OrderSerializer 

    def get_queryset(self):
        queryset = Order.objects.filter(customer_id=self.kwargs["customer_pk"]).get(order_number=self.kwargs["pk"])
        return queryset

urls.py

from django.urls import path

from .views import *

urlpatterns = [   
    path('<int:customer_pk>/orders/<int:pk>/', OrderDetailView.as_view()),    
]
Asked By: mRezaAnanta

||

Answers:

filter Query with multiple parameters

queryset = Order.objects.filter(customer_id=self.kwargs["customer_pk"],order_number=self.kwargs["orde_pk"])

We can override queryset:

class OrderDetailView(generics.RetrieveDestroyAPIView):
    lookup_field = "pk"
    serializer_class = OrderSerializer 

    def get_queryset(self):
        return Order.objects.filter(customer_id=self.kwargs["customer_pk"])

Just it, retrieve object Order already handled by get_object() method.


If want more secure, make sure customer is valid (customer is available):

from django.shortcuts import get_object_or_404

class OrderDetailView(generics.RetrieveDestroyAPIView):
    lookup_field = "pk"
    serializer_class = OrderSerializer 

    def get_customer(self):
        return get_object_or_404(
            Customer.objects.all(),
            id=self.kwargs["customer_pk"]
        )

    def get_queryset(self):
        customer = self.get_customer()
        return Order.objects.filter(customer=customer)
Answered By: Mahrus Khomaini