乘以2列和分组

时间:2017-09-05 11:47:05

标签: python django django-rest-framework

我正在尝试通过Django ORM进行SQL查询:

SELECT SUM(((BUY_UNITS*BUY_NAV)-(SELL_UNITS*SELL_NAV))) AS NET_CAP, PRODUCT FROM TRADING_DB.OPEN_MUTUAL_FUND_POSITIONS
GROUP BY PRODUCT;

所以我最初做了类似的事情:

MutualFundPositions.objects.filter(client_id=X1234).annotate(net_cap=Sum(("buy_units" * "buy_nav") - ("sell_units" * "sell_nav"))).values('product', 'net_cap')

没有用,所以我尝试在django中使用F,

MutualFundPositions.objects.filter(client_id=X1234).annotate(net_cap = F(F('buy_units') * F('buy_nav')) - F('sell_units') * F('sell_nav')).values('product', 'net_cap')

AttributeError at /client/details/capital/ 'CombinedExpression' object has no attribute 'split'

Models.py:

class MutualFundPositions(models.Model):
    client_id = models.CharField(db_column='CLIENT_ID', max_length=45, primary_key=True)
    mf_name = models.CharField(db_column='MF_NAME', max_length=100)  
    buy_units = models.DecimalField(db_column='BUY_UNITS', max_digits=10, decimal_places=5)  
    buy_nav = models.DecimalField(db_column='BUY_NAV', max_digits=10, decimal_places=5) 
    sell_units = models.DecimalField(db_column='SELL_UNITS', max_digits=10, decimal_places=5) 
    sell_nav = models.DecimalField(db_column='SELL_NAV', max_digits=10, decimal_places=5)
    current_nav = models.DecimalField(db_column='CURRENT_NAV', max_digits=10, decimal_places=5) 
    product = models.CharField(db_column='PRODUCT', max_length=45, blank=True, null=True)
    date = models.DateField(db_column='DATE', blank=True, null=True)  

    class Meta:
        db_table = 'OPEN_MUTUAL_FUND_POSITIONS'

serializer.py:

class MutualFundSerializer(serializers.ModelSerializer):
    pandl = serializers.SerializerMethodField()

    class Meta:
        model = MutualFundPositions
        fields = ['mf_name', 'product', 'buy_units', 'buy_nav', 'sell_units', 'sell_nav', 'pandl','current_nav', 'date']

    def get_pandl(self, instance):
        net_qty = abs(instance.buy_units - instance.sell_units)
        net_nav = instance.current_nav - instance.buy_nav
        return net_qty * net_nav

我在这里做错了什么?

1 个答案:

答案 0 :(得分:0)

您可以使用ExpressionWrapper来实现此目的

from django.db.models import ExpressionWrapper, F, FloatField

MutualFundPositions.objects.filter(
    client_id=X1234
).values(
    'product'
)annotate(
    net_cap=Sum(
        ExpressionWrapper(
            ExpressionWrapper(F('buy_units') * F('buy_nav'), 
                              output_field=FloatField()) - \
            ExpressionWrapper(F('sell_units') * F('sell_nav'),
                              output_field=FloatField()),
            output_field=FloatField(),
        ),
)

每个数学运算都包含在ExpressionWrapper下,因此我们使用其中三个:两次乘法和一次减法