Home > Back-end >  How to fetch with multiple query parameters Genereic API view
How to fetch with multiple query parameters Genereic API view

Time:07-21

so I am building an API and i want to fetch based on multiple parameters.

Here is the code base.

The Url path:

path('<str:order_id>/consumers/', SingleConsumerTradeAPIView.as_view(), name="single-consumer-trade" ),
path('<str:order_id>/producers/', SingleProducerTradeAPIView.as_view(), name="single-producer-trade" ),

Models.py:

from django.db import models
from authApi.models import User

class Order(models.Model):
    user = models.ForeignKey(User,related_name='user',null=True, on_delete=models.CASCADE)
    date = models.DateField(auto_now_add=True)

class Trade(models.Model):
    consumer = models.ForeignKey(User,related_name='consumer',on_delete=models.CASCADE)
    producer = models.ForeignKey(User,related_name='producer',on_delete=models.CASCADE)
    order = models.ForeignKey(Order, related_name='trades',on_delete=models.CASCADE)
    price = models.DecimalField(max_digits=10, max_length=255, decimal_places=2)
    location = models.CharField(max_length=255)
    energyQuantity = models.DecimalField(max_digits=10, max_length=255, decimal_places=2)
    startTime = models.DateField(auto_now_add=True)
    stopTime = models.DateField(auto_now_add=True)

Serializers.py:

class TradeSerializer(serializers.ModelSerializer):
    class Meta:
        model = Trade
        fields = ('id',
                  'order_id',
                  'startTime',
                  'stopTime',
                  'price',
                  'consumer_id',
                  'producer_id',
                  'location',
                  'energyQuantity',
                )


class OrderSerializer(serializers.ModelSerializer):
    trades = TradeSerializer(read_only=True, many= True)
    class Meta:
        model = Order
        fields = ('id',
                  'trades',
                  'date',
                )

What i tried:

Views

class SingleProducerTradeAPIView(ListCreateAPIView):
    serializer_class=TradeSerializer
    queryset = Trade.objects.all()
    permission_classes = (permissions.IsAuthenticated,)
    lookup_fields = ('order_id', 'producer_id')

    def list(self, *args, **kwargs):
        order_id = kwargs.get('order_id')
        user = self.request.user
        try:
            trades = Trade.objects.filter(order_id=order_id,consumer_id=user)
        except Trade.DoesNotExist: 
            return JsonResponse({'message': 'The user does not exist'}, status=status.HTTP_404_NOT_FOUND) 
        order_serializer = TradeSerializer(trades, many=True) 
        return JsonResponse(order_serializer.data, safe=False) 
    
    def perform_create(self, serializer):
        return serializer.save(consumer_id=self.request.user)

I want to be able to fetch from the list of trades(via the trade model and serializers) using the order_id and the producer_id.

CodePudding user response:

Django will send the parameters from the URL into the view functions are keyword arguments (**kwargs)

class SingleConsumerTradeAPIView(ListCreateAPIView):
    serializer_class=TradeSerializer
    queryset = Trade.objects.all()
    permission_classes = (permissions.IsAuthenticated,)
    lookup_fields = ('order_id', 'producer_id')

    def list(self, *args, **kwargs):
        order_id = kwargs.get('order_id')
        user_id = kwargs.get('user_id')

        # do some work with order_id and user_id
    
    def get_queryset(self):
        return self.queryset.filter(order_id=self.request.user,producer_id=
self.request.user)

CodePudding user response:

Here you can directly use the get_queryset method and you will definitely get the parameters from kwargs of the get_queryset method and you can remove the queryset variable from the class and directly hit the query in the get_queryset method. It will save time by hitting the database only once. there is no need for lookup_fields too so you can remove it.

class SingleConsumerTradeAPIView(ListCreateAPIView):
    serializer_class=TradeSerializer
    permission_classes = (permissions.IsAuthenticated,)
    lookup_fields = ('order_id', 'producer_id')

    
    def get_queryset(self, *args, **kwargs):
        return Trade.objects.filter(order_id=kwargs.get('order_id'),producer_id=
self.request.user)
  • Related