Я работаю на веб-сайте django для отслеживания устройств в сети.
У меня есть модель Device
:
class DeviceManager(models.Manager):
def get_queryset(self):
return super().get_queryset().annotate(
num_interfaces=Count('interface', distinct=True))
class Device(models.Model):
objects = DeviceManager()
uuid = models.UUIDField()
name = models.CharField(max_length=30)
class Meta:
_base_manager = DeviceManager()
, а затем у меня есть модель Interface
:
from .models import Device
class Interface(models.Model):
ip = models.GenericIPAddressField()
device = models.ForeignKey(Device, on_delete=models.CASCADE)
При отображении списка устройств мне нужно указать количество интерфейсов для каждого устройства. Поэтому я создал диспетчер, который извлекает счет одним запросом, вместо того, чтобы иметь отдельный запрос для каждого устройства в списке.
Теперь я хочу отобразить случайный IP-адрес для каждого устройства. Это не так, если устройство имеет несколько интерфейсов.
Я начал писать еще один .annotate
в свой DeviceManger
, и я не уверен, что делать.
Я думал об использовании подзапроса, что-то вроде:
subquery = Interface.objects.filter(ip=OuterRef('ip'))
так:
class DeviceManager(models.Manager):
def get_queryset(self):
subquery = Interface.objects.filter(device_id=OuterRef('device'))
return super().get_queryset().annotate(
num_interfaces=Count('interface', distinct=True)).annotate(
ip=Coalesce(Min(Subquery(subquery('ip'))), None)
Но потом я понял, что Interface
зависит от Device
, и поэтому я не могу обратиться к Interface
до тех пор, пока Device
не будет полностью определено, поэтому определенно не в DeviceManager
Каков наилучший способ сделать это?