2017-09-05 55 views
0

我想通過Django的ORM做一個SQL查詢:乘間2列和集團通過

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') 

沒有工作,所以我試着做用F Django的它,

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 

我到底做錯了什麼?

回答

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包裹,因此我們使用他們三個人:兩個乘法和一個減法