简体   繁体   中英

Django AttributeError: 'int' object has no attribute 'pk'

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM