Combining two different serializers into one view

2019-08-17 13:03发布

问题:

I need to combine two views into a single view.

The final combined response should be like this :

{
    "**EQUITY**": [{
        "SYMBOL": "INFY",
        "BUY_QTY": 10,
        "BUY_RATE": 1010.01
    }, {
        "SYMBOL": "TCS",
        "BUY_QTY": 10,
        "BUY_RATE": 1010.01
    }, {
        "SYMBOL": "MARUTI",
        "BUY_QTY": 10,
        "BUY_RATE": 1010.01
    }],
    "**FNO**": {
        "**OPTIONS**": [{
            "SYMBOL": "INFY",
            "EXPIRY_DATE": "2017-07-18",
            "STRIKE": 1200,
            "OPT_TYPE": "CE",
            "BUY_QTY": 10,
            "BUY_RATE": 1010.01,
            "SELL_QTY": 0,
            "SELL_RATE": 0,
            "DIRECTION": "LONG"
        }, {
            "SYMBOL": "NIFTY",
            "EXPIRY_DATE": "2017-07-18",
            "STRIKE": 9200,
            "OPT_TYPE": "PE",
            "BUY_QTY": 10,
            "BUY_RATE": 1010.01,
            "SELL_QTY": 0,
            "SELL_RATE": 0,
            "DIRECTION": "SHORT"
        }],
        "**FUTURES**": [{
            "SYMBOL": "INFY",
            "EXPIRY_DATE": "2017-07-18",
            "BUY_QTY": 10,
            "BUY_RATE": 1010.01,
            "SELL_QTY": 0,
            "SELL_RATE": 0,
            "DIRECTION": "LONG"
        }, {
            "SYMBOL": "NIFTY",
            "EXPIRY_DATE": "2017-07-18",
            "BUY_QTY": 10,
            "BUY_RATE": 1010.01,
            "SELL_QTY": 0,
            "SELL_RATE": 0,
            "DIRECTION": "SHORT"
        }]
    }
}

Initially I had made this into two separate end points but now the requirement is such that both the serializer responses should be in a single view. How can i club both of these serializers into one single view?

This is my views.py

from rest_framework.generics import ListAPIView
from rest_framework.permissions import IsAuthenticated
from .serializers import *
from .models import EquityPositions


class EquityPositionListView(ListAPIView):
    serializer_class = EquityPositionSerializer
    permission_classes = [IsAuthenticated]

    def get_queryset(self):
        print("logged in user ==== >", self.request.user.username)
        return EquityPositions.objects.using('tradingdb').filter(client_id=self.request.user.username, status="OPEN")


class FnoPositionListView(ListAPIView):
        serializer_class = FnoPositionsSerializer
        permission_classes = [IsAuthenticated]

        def get_queryset(self):
            print("logged in user ==== >", self.request.user.username)
            return FnoPositions.objects.using('tradingdb').filter(client_id=self.request.user.username)

This is my serializers.py

from rest_framework import serializers
from .models import *

class EquityPositionSerializer(serializers.ModelSerializer):
    net_qty = serializers.SerializerMethodField()

    class Meta:
        model = EquityPositions
        fields = ['net_qty', 'symbol', 'buy_qty', 'buy_rate']

    def get_net_qty(self, instance):
        return instance.buy_qty - instance.sell_qty


class FnoPositionsSerializer(serializers.ModelSerializer):
    net_qty = serializers.SerializerMethodField()

    class Meta:
        model = FnoPositions
        fields = ['net_qty','symbol','expiry_date','strike_price','buy_qty','sell_qty','direction']

    def get_net_qty(self, instance):
        return abs(instance.sell_qty - instance.buy_qty)

Here are my Models:

class EquityPositions(models.Model):
    pos_id = models.AutoField(db_column='POS_ID', primary_key=True)
    client_id = models.CharField(db_column='CLIENT_ID', max_length=25)
    symbol = models.CharField(db_column='SYMBOL', max_length=100)
    buy_qty = models.IntegerField(db_column='BUY_QTY', blank=True, null=True)
    buy_rate = models.DecimalField(db_column='BUY_RATE', max_digits=15, decimal_places=2, blank=True, null=True)
    sell_qty = models.IntegerField(db_column='SELL_QTY', blank=True, null=True)
    sell_rate = models.DecimalField(db_column='SELL_RATE', max_digits=10, decimal_places=2, blank=True, null=True)
    pandl = models.DecimalField(db_column='PANDL', max_digits=10, decimal_places=2, blank=True, null=True)
    status = models.CharField(db_column='STATUS', max_length=10)
    tax = models.DecimalField(db_column='TAX', max_digits=10, decimal_places=2)
    brokrage = models.DecimalField(db_column='BROKRAGE', max_digits=10, decimal_places=2)
    product = models.CharField(db_column='PRODUCT', max_length=45, blank=True, null=True)

    class Meta:
        managed = False
        db_table = 'EQUITY_POSITIONS'


class FnoPositions(models.Model):
    pos_id = models.AutoField(db_column='POS_ID', primary_key=True)
    client_id = models.CharField(db_column='CLIENT_ID', max_length=25)
    symbol = models.CharField(db_column='SYMBOL', max_length=100)
    instrument = models.CharField(db_column='INSTRUMENT', max_length=20)
    expiry_date = models.DateField(db_column='EXPIRY_DATE')
    strike_price = models.DecimalField(db_column='STRIKE_PRICE', max_digits=20, decimal_places=4, blank=True, null=True)
    option_type = models.CharField(db_column='OPTION_TYPE', max_length=5, blank=True, null=True)
    buy_qty = models.IntegerField(db_column='BUY_QTY')
    buy_rate = models.DecimalField(db_column='BUY_RATE', max_digits=20, decimal_places=4)
    sell_qty = models.IntegerField(db_column='SELL_QTY')
    sell_rate = models.DecimalField(db_column='SELL_RATE', max_digits=20, decimal_places=4)
    pandl = models.DecimalField(db_column='PANDL', max_digits=20, decimal_places=4)
    direction = models.CharField(db_column='DIRECTION', max_length=10)
    status = models.CharField(db_column='STATUS', max_length=10)
    brokerage = models.DecimalField(db_column='BROKERAGE', max_digits=20, decimal_places=4)
    tax = models.DecimalField(db_column='TAX', max_digits=20, decimal_places=4)
    product = models.CharField(db_column='PRODUCT', max_length=45, blank=True, null=True)

    class Meta:
        managed = False
        db_table = 'FNO_POSITIONS'

回答1:

You can override the list method for new view listmodelmixin:

class CombineListView(ListAPIView):
    serializer_class_Equity = EquityPositionSerializer
    serializer_class_Fno = FnoPositionsSerializer

    def get_queryset_Equity(self):
        return EquityPositions.objects.using('tradingdb').filter(client_id=self.request.user.username,
                                                                 status="OPEN")
    def get_queryset_Fno(self):
        return FnoPositions.objects.using('tradingdb').filter(client_id=self.request.user.username)

    def list(self, request, *args, **kwargs):
        fno = self.serializer_class_Fno(self.get_queryset_Fno(), many=True)
        equity = self.serializer_class_Equity(self.get_queryset_Equity(), many=True)
        return Response({
            "**EQUITY**": equity.data,
            "**FNO**": fno.data
        })