Reputation: 148
When I request GET through DRF API, I want to return the latest object. I tried this one in views.py:
class ListCreateNodeConfig(generics.ListCreateAPIView):
queryset = models.NodeConfig.objects.all()
serializer_class = serializers.NodeConfigSerializer
def get_queryset(self):
return self.queryset.filter(node_id=self.kwargs.get('node_pk')).latest('timestamp')
But it throws error: 'NodeConfig' object is not iterable
models.py
class NodeConfig(models.Model):
node_id = models.ForeignKey(Node)
timestamp = models.DateTimeField(auto_now_add=True, auto_now=False)
record_interval = models.IntegerField(default=0)
lower_frequency = models.IntegerField(default=0)
upper_frequency = models.IntegerField(default=0)
How to fix it?
Any suggestions are appreciated.
Upvotes: 3
Views: 7115
Reputation: 97
You could also use python slicing for return single object into queryset:
self
.queryset
.filter(node_id=self.kwargs.get('node_pk'))
.order_by('-timestamp')[:1]
Upvotes: 0
Reputation: 2970
The porblem here ist the latest()
method. This does not return a queryset but a single model instance. (like get(...)
)
so use:
def get_queryset(self):
return self.queryset.filter(node_id=self.kwargs.get('node_pk')).order_by('-timestamp')
So if you want to have an endpoint for a single object you must not use DRF List*
views/mixins.
The listviews assume you want to work with lists (=multiple objects). And so they rely on queryset
resp. get_queryset
. And a queryset should obviously be a queryset and not a model instance...
But there is also the RetrieveAPIView
view included:
from rest_framework.generics import RetrieveAPIView
class LatestNodeConfigView(RetrieveAPIView):
queryset = models.NodeConfig.objects.all()
# add your serializer
serializer_class = NodeConfigDetailSerializer
def get_object(self, *args, **kwargs):
return self.queryset.filter(node_id=kwargs.get('node_pk')).latest('timestamp')
Upvotes: 9