Django множественная фильтрация «многие ко многим» - PullRequest
0 голосов
/ 12 февраля 2020

У меня есть модель, которая выглядит следующим образом:

class NetworkDevice(models.Model):
    name = models.CharField(max_length=30)

class NetworkInterface(models.Model):
    intname = models.CharField(max_length=30)
    device = models.ForeignKey(NetworkDevice)

class NetworkMac(models.Model):
    macaddr = models.CharField(max_length=30)
    interface = models.ManyToManyField(NetworkInterface)

Я хочу создать страницу сведений об устройстве, которая отображает только MAC-адреса, извлеченные из интерфейсов, назначенных этому конкретному устройству. Проблема в том, что один и тот же адрес ma c живет на разных интерфейсах на разных устройствах. если я передаю свой шаблон что-то вроде:

macs = NetworkMac.objects.filter(interface__device__name='<some device name>')

Это дает мне все адреса MA C для этого устройства, но поскольку MAC-адреса являются общими, это также дает мне MAC-адреса, связанные с интерфейсами на других устройства. Поэтому, когда я пытаюсь отобразить это в своем шаблоне, он перестает давать мне ничего или, если я использую |first, он часто дает мне интерфейс для другого устройства в зависимости от порядка добавления устройств в базу данных.

Что мне действительно нужно, так это запрос, который я могу запустить и который вернет все маки для одного устройства, изученного только на интерфейсах, связанных с этим устройством.

Обновление: Просто дать немного больше деталей. Способ, которым я сейчас обхожу это, состоит в том, чтобы определить метод, на мой взгляд, так ...

class DeviceDetailView(generic.DetailView):
    template_name = 'NetViewer/Device_detail_template.html'
    model = NetworkDevice

    def mac_ip_table(self, device_pk):
        ints = NetworkInterface.objects.filter(hostdevice__hostname=device_pk.hostname)
        mac_list = []
        for int in ints:
            for mac in int.networkmacs.all():
                ip_qs = NetworkIP.objects.filter(mac__macaddr=mac.macaddr)
                ip_list = [ip.ip for ip in ip_qs]
                mac_list.append(tuple([mac.macaddr, ip_list, int.intname]))
        return mac_list

    def get(self, request, *args, **kwargs):
        device = NetworkDevice.objects.get(pk=self.kwargs.get('pk'))
        args = {'macs': self.mac_ip_table(device), 'device': device}

        return render(request, self.template_name, args)

Тогда я прохожу oop через то, что mac_ip_table возвращает в моем шаблоне. Недостатком этого является то, что это действительно неэффективно и, вероятно, сделает пагинацию невозможной.

Когда я прыгаю через несколько моделей, например ...

macs = NetworkMac.objects.filter(interface__hostdevice__hostname=device_pk.hostname)

Мне нужен способ фильтрации этого запроса только для интерфейсов, которые связаны с устройством , Я относительно новичок в Django, так что не делайте мне больно, если этот вопрос совершенно не соответствует действительности или я что-то упустил полностью

1 Ответ

0 голосов
/ 12 февраля 2020

Это должно быть полезно:

 macs = NetworkMac.objects.filter(interface__exact='<some device name>')
...