I am stuck:(. I have an API that I can't seem to get working with the DRF. I am forming my queryset in my view and the result that I want is coming out in the console:
web_1 | {'company_exchange': 969, 'company_exchange__company__name': 'LIGHTSPEED POS', 'company_exchange__stock_symbol': 'LSPD', 'strategy': 1, 'periodic_buy_period': 5, 'periodic_sell_period': 10, 'month': datetime.datetime(2021, 11, 1, 0, 0, tzinfo=<UTC>), 'periodic_sum': Decimal('1.2300000000')}
web_1 | {'company_exchange': 969, 'company_exchange__company__name': 'LIGHTSPEED POS', 'company_exchange__stock_symbol': 'LSPD', 'strategy': 1, 'periodic_buy_period': 2, 'periodic_sell_period': 14, 'month': datetime.datetime(2021, 12, 1, 0, 0, tzinfo=<UTC>), 'periodic_sum': Decimal('7.4200000000')}
web_1 | {'company_exchange': 969, 'company_exchange__company__name': 'LIGHTSPEED POS', 'company_exchange__stock_symbol': 'LSPD', 'strategy': 1, 'periodic_buy_period': 13, 'periodic_sell_period': 11, 'month': datetime.datetime(2021, 12, 1, 0, 0, tzinfo=<UTC>), 'periodic_sum': Decimal('100.9600000000')}
I can see that the obj gets passed into my serializer, but for the life of me I can not understand where I am going wrong.
Here is my view.py
class TopHistoricalGainViewSet(viewsets.ModelViewSet):
queryset = TopHistoricalGains.objects.all()
serializer_class = TopHistoricalGainsSerializer
def get_queryset(self):
ids = self.queryset\
.values('id')\
#commented out as I don't need this just yet `#.distinct('company_exchange__id')\`
.order_by('company_exchange__id')
twelve_months_ago = datetime.datetime.now()+relativedelta(months=-12)
hg_list = TopHistoricalGains.objects.filter(id__in=ids, periodic_date_time__gte=twelve_months_ago)
hg_list = hg_list\
.annotate(month=TruncMonth('periodic_date_time')) \
.values('month') \
.annotate(periodic_sum=Sum('periodic_gain_max')) \
.values('company_exchange', 'company_exchange__company__name', 'company_exchange__stock_symbol', 'month', 'periodic_sum', 'strategy', 'periodic_buy_period', 'periodic_sell_period') \
#.order_by('company_exchange', '-periodic_sum', 'strategy', 'periodic_buy_period', 'periodic_sell_period')[:10]
for hg in hg_list:
print(hg)
return hg_list
class Meta:
ordering = ['periodic_sum', 'company_exchange']
Serializers.py
class TopHistoricalGainsSerializer(serializers.ModelSerializer):
first_bought = serializers.SerializerMethodField()
last_sold = serializers.SerializerMethodField()
company_exchange_name = serializers.SerializerMethodField()
company_exchange_stock_symbol = serializers.SerializerMethodField()
class Meta:
model = TopHistoricalGains
fields = (
'company_exchange_id', 'company_exchange_name', 'company_exchange_stock_symbol', 'strategy', 'periodic_date_time', 'periodic_gain_max', 'periodic_buy_period', 'periodic_sell_period','first_bought', 'last_sold'
)
def get_first_bought(self, obj):
try:
BuySellEvent = apps.get_model("calculations", "BuySellEvent")
buy_sell = BuySellEvent.objects.filter(company_exchange=obj['company_exchange'], strategy=obj['strategy'], buy_period=obj['periodic_buy_period'], sell_period=obj['periodic_sell_period']).earliest('buy_date_time')
if buy_sell:
lb = buy_sell.buy_date_time
else:
lb = None
except BuySellEvent.DoesNotExist:
lb = None
return lb
def get_last_sold(self, obj):
try:
BuySellEvent = apps.get_model("calculations", "BuySellEvent")
buy_sell = BuySellEvent.objects.filter(company_exchange=obj['company_exchange'], strategy=obj['strategy'], buy_period=obj['periodic_buy_period'], sell_period=obj['periodic_sell_period']).latest('sell_date_time')
if buy_sell:
ls = buy_sell.sell_date_time
else:
ls = None
except BuySellEvent.DoesNotExist:
ls = None
return ls
def get_company_exchange_name(self, obj):
return obj['company_exchange__company__name'] if obj and obj['company_exchange__company__name'] else 'N/A'
def get_company_exchange_stock_symbol(self, obj):
return obj['company_exchange__company__name'] if obj and obj['company_exchange__company__name'] else 'N/A'
Error:
web_1 | {'company_exchange': 969, 'company_exchange__company__name': 'LIGHTSPEED POS', 'company_exchange__stock_symbol': 'LSPD', 'strategy': 1, 'periodic_buy_period': 5, 'periodic_sell_period': 10, 'month': datetime.datetime(2021, 11, 1, 0, 0, tzinfo=<UTC>), 'periodic_sum': Decimal('1.2300000000')}
web_1 | {'company_exchange': 969, 'company_exchange__company__name': 'LIGHTSPEED POS', 'company_exchange__stock_symbol': 'LSPD', 'strategy': 1, 'periodic_buy_period': 2, 'periodic_sell_period': 14, 'month': datetime.datetime(2021, 12, 1, 0, 0, tzinfo=<UTC>), 'periodic_sum': Decimal('7.4200000000')}
web_1 | {'company_exchange': 969, 'company_exchange__company__name': 'LIGHTSPEED POS', 'company_exchange__stock_symbol': 'LSPD', 'strategy': 1, 'periodic_buy_period': 13, 'periodic_sell_period': 11, 'month': datetime.datetime(2021, 12, 1, 0, 0, tzinfo=<UTC>), 'periodic_sum': Decimal('100.9600000000')}
web_1 | /usr/local/lib/python3.8/site-packages/rest_framework/pagination.py:200: UnorderedObjectListWarning: Pagination may yield inconsistent results with an unordered object_list: <class 'apps.calculations.models.TopHistoricalGains'> QuerySet.
web_1 | paginator = self.django_paginator_class(queryset, page_size)
web_1 | Internal Server Error: /calculations/api/max-historical-gains/
web_1 | Traceback (most recent call last):
web_1 | File "/usr/local/lib/python3.8/site-packages/django/core/handlers/exception.py", line 47, in inner
web_1 | response = get_response(request)
web_1 | File "/usr/local/lib/python3.8/site-packages/django/core/handlers/base.py", line 181, in _get_response
web_1 | response = wrapped_callback(request, *callback_args, **callback_kwargs)
web_1 | File "/usr/local/lib/python3.8/site-packages/django/views/decorators/csrf.py", line 54, in wrapped_view
web_1 | return view_func(*args, **kwargs)
web_1 | File "/usr/local/lib/python3.8/site-packages/rest_framework/viewsets.py", line 125, in view
web_1 | return self.dispatch(request, *args, **kwargs)
web_1 | File "/usr/local/lib/python3.8/site-packages/rest_framework/views.py", line 509, in dispatch
web_1 | response = self.handle_exception(exc)
web_1 | File "/usr/local/lib/python3.8/site-packages/rest_framework/views.py", line 469, in handle_exception
web_1 | self.raise_uncaught_exception(exc)
web_1 | File "/usr/local/lib/python3.8/site-packages/rest_framework/views.py", line 480, in raise_uncaught_exception
web_1 | raise exc
web_1 | File "/usr/local/lib/python3.8/site-packages/rest_framework/views.py", line 506, in dispatch
web_1 | response = handler(request, *args, **kwargs)
web_1 | File "/usr/local/lib/python3.8/site-packages/rest_framework/mixins.py", line 43, in list
web_1 | return self.get_paginated_response(serializer.data)
web_1 | File "/usr/local/lib/python3.8/site-packages/rest_framework/serializers.py", line 745, in data
web_1 | ret = super().data
web_1 | File "/usr/local/lib/python3.8/site-packages/rest_framework/serializers.py", line 246, in data
web_1 | self._data = self.to_representation(self.instance)
web_1 | File "/usr/local/lib/python3.8/site-packages/rest_framework/serializers.py", line 663, in to_representation
web_1 | return [
web_1 | File "/usr/local/lib/python3.8/site-packages/rest_framework/serializers.py", line 664, in <listcomp>
web_1 | self.child.to_representation(item) for item in iterable
web_1 | File "/usr/local/lib/python3.8/site-packages/rest_framework/serializers.py", line 515, in to_representation
web_1 | ret[field.field_name] = field.to_representation(attribute)
web_1 | File "/usr/local/lib/python3.8/site-packages/rest_framework/relations.py", line 271, in to_representation
web_1 | return value.pk
web_1 | AttributeError: 'int' object has no attribute 'pk'
web_1 | [30/Dec/2021 02:12:05] "GET /calculations/api/max-historical-gains/ HTTP/1.1" 500 144664
web_1 | Not Found: /favicon.ico
My goal is to pull data from the TopHistoricalGains Table and produce a top 10 list that is based on the sum of the periodic_gain_max by month.
I assume I am doing several things wrong. But can not seem to figure out where this 'int' object has no attribute 'pk' is occuring.
Any help? Thanks and Cheers!
I had the same problem as you, and what helped me was changing the 'values' to 'only'. According to this link ( https://books.agiliq.com/projects/django-orm-cookbook/en/latest/select_some_fields.html ) the difference is that 'only' also fetches the id. I approached the serializers differently tho so I am not sure if it will help, but maybe worth a try?
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.