I need to list all my devices. To do this I use a prefetch related to reduce the amount of queries. But one of them is consuming to much time.. I wonder if it can't go better.
I will start with the model constructions: I want a list of devices.
class Device(models.Model):
name = models.CharField(max_length=250, null=True, blank=True)
class GatewayDevice(models.Model):
gateway = models.ForeignKey(
Gateway, on_delete=models.CASCADE, related_name="devices"
)
device = models.ForeignKey(
Device, on_delete=models.CASCADE, related_name="gatewaydevices"
)
In the real code the device model is larger, but that code is irrelevant. As you can see, a device has some gatewaydevices (which is a model between gateway and device)
So in my list of devices, I want for every device, the linked gateway.
This is my view:
class AdminDeviceView(GenericAPIView):
def get_permissions(self):
return IsAuthenticated()
# noinspection PyMethodMayBeStatic
def get_serializer_class(self):
return AdminDeviceInfoSerializer
@swagger_auto_schema(
responses={
200: openapi.Response(
_("Successfully fetched all data from devices."),
AdminDeviceInfoSerializer,
)
}
)
def get(self, request):
"""
GET the data from all the devices.
"""
devices = (
Device.objects.filter()
.all()
.prefetch_related(
"site__users",
"software_update_history",
"supplier",
Prefetch(
"gatewaydevices",
queryset=GatewayDevice.objects.filter(end_date=None)
.order_by()
.distinct()
.prefetch_related("gateway"),
),
)
)
serializer_class = self.get_serializer_class()
serializer = serializer_class(devices, many=True)
devices_data = serializer.data
return Response(
{"total": devices.count(), "items": devices_data}, status=status.HTTP_200_OK
)
This is the part of the serializer that is important:
@staticmethod
def get_gateway(device):
return (
GatewaySimpleSerializer(device.gatewaydevices.gateway).data
if device.gatewaydevices.gateway
else None
)
I tried different approaches. This one is the current one.. Now I get this error:
AttributeError: 'RelatedManager' object has no attribute 'gateway'