Как перечислить все объекты и получить один объект, используя общие представления django drf
Я пытаюсь создать представление на основе одного класса для повторного просмотра, перечисления и создания всех моих заказов. Мне удалось заставить работать create и retirve, но listing вызывает некоторые проблемы. Я использую DRF generic views для расширения представления и добавил generics.ListApiView в свой класс. Однако, как только я его добавил, мой маршрут retirve начал вести себя необычно. Он возвращает мне список всех заказов, когда мне нужен только конкретный заказ.
Я пытался просто добавить generics.ListApiView в свой класс и переопределить функции list и get_queryset, но это только начало влиять на мой retrive view.
class Order(generics.ListAPIView, generics.CreateAPIView, generics.RetrieveAPIView):
permission_classes = (permissions.IsAuthenticated,)
serializer_class = addOrderSerializer
def get_queryset(self, **kwargs):
user = self.request.user
return Order.objects.filter(user=user)
def get_object(self):
pk = self.kwargs['pk']
obj = Order.objects.get(pk=pk)
return obj
def get_item_serializer(self, *args, **kwargs):
return addItemSerializer(*args, **kwargs)
def get_shipping_serializer(self, *args, **kwargs):
return addShippingSerializer(*args, **kwargs)
def create(self, request, *args, **kwargs):
user = request.user
data = request.data
orderItems = data.get('orderItems')
print(data)
if not bool(orderItems):
return Response('No Order Items', status=status.HTTP_400_BAD_REQUEST)
else:
# TODO - Create Order
orderSerializer = self.get_serializer(data=data)
orderSerializer.is_valid(raise_exception=True)
order = orderSerializer.save(user=user)
# TODO - Create Shipping Address
shippingSerializer = self.get_shipping_serializer(data=data)
shippingSerializer.is_valid(raise_exception=True)
shippingSerializer.save(order=order)
# TODO - Create Order Items and Set Order <> OrderItem Relationship
for item in orderItems:
product = Product.objects.get(pk=item['product'])
itemSerializer = self.get_item_serializer(data=item)
itemSerializer.is_valid(raise_exception=True)
item = itemSerializer.save(order=order, product=product)
# # TODO - Update Product CountInStock
product.countInStock -= item.qty
product.save()
return Response(data=orderSerializer.data)
def retrieve(self, request, *args, **kwargs):
instance = self.get_object()
s = self.get_serializer(instance=instance)
return Response(data=s.data)
def list(self, request, *args, **kwargs):
qs = self.get_queryset()
s = self.get_serializer(qs, many=True)
return Response(s.data)
В заключение, функциональность списка в моем представлении теперь работает, но это испортило мою retive функциональность. Так что функция retive возвращает только список, несмотря на то, что я добавляю pk в мой url.
Не могли бы вы также опубликовать ваш urls.py для большей ясности?
В настоящее время, исходя из вашего вопроса, проблема, которую я вижу, указана ниже:
- Вы вызываете класс "Order" для метода retrieve с некоторым шаблоном url, например path/int:pk -- Что является GET запросом
- Вы также вызываете тот же класс "Order" для метода list с некоторым шаблоном url, например path/ -- Что является Get запросом .
Проблема в том, что и Retrieve, и List Generic api имеют метод GET: добавлен сниппет :
Заключение:
Это пример порядка разрешения методов в наследовании в python.
Поэтому, несмотря на то, что вы пытаетесь вызвать метод GET для получения, он вызывает метод GET из LIST api, потому что в определении вашего класса
class Order(generics.ListAPIView, generics.CreateAPIView, generics.RetrieveAPIView) вы сначала унаследовали ListAPIView.
Решение :
- Вам следует разделить классы, например: ListCreateAPIView, RetrieveUpdateDestroyAPIView .
Альтернативный вариант : Вы также можете следовать приведенному ниже ответу stackoverflow для маршрутизации GET-запроса к определенному методу в том же классе :
Множество методов get в одном классе в представлениях Django