Получение объекта с использованием нескольких параметров внутри урла в 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)