Получение объекта с использованием нескольких параметров внутри урла в Django-Rest-Framework

Как получить объект, используя несколько параметров в url? Пример: 'customer/3/order/1/' или 'customer/<int:customer_pk>/order/<int:pk>/'

Используя shell, я могу получить объект таким образом, но я не могу сделать это из представления.

>>> 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 CustomerListView(generics.ListCreateAPIView):
    queryset = Customer.objects.all()
    serializer_class = CustomerSerializer

class CustomerDetailView(generics.RetrieveDestroyAPIView):
    queryset = Customer.objects.all()
    serializer_class = CustomerSerializer

class OrderListView(generics.ListCreateAPIView):
    def get_queryset(self):
        queryset = Order.objects.filter(customer_id=self.kwargs["pk"])
        return queryset
    serializer_class = OrderSerializer

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('', CustomerListView.as_view()),    
    path('<int:pk>/', CustomerDetailView.as_view()),    
    path('<int:pk>/orders/', OrderListView.as_view()),    
    path('<int:customer_pk>/orders/<int:pk>/', OrderDetailView.as_view()),    
]

Запрос фильтра с несколькими параметрами

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

Мы можем переопределить 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"])

Просто так, извлечение объекта Order уже обработано методом get_object().


Если вы хотите повысить безопасность, убедитесь, что клиент действителен (клиент доступен):

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)
Вернуться на верх