Django Фильтр запросов по отношениям "многие ко многим

class servers(models.Model):
hostname=models.CharField(max_length=100)
ip= models.CharField(max_length=100)
os= models.CharField(max_length=100)

class application(models.Model)
name=models.CharField(max_length=100)
URL= models.CharField(max_length=100)
servers= models.ManyToManyField(servers, blank = True, null=True)

текущее состояние БД

3 сервера 2 с ОС linux и 1 с ОС windows

2 приложения

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

def viewapp(request,pk)
criterion1 = Q(id=pk)
criterion2 = Q(servers__os__startswith="windows")
prodlist = application.objects.filter(criterion1 & criterion2)  

Вы можете фильтровать поле "многие ко многим" также с помощью объекта Prefetch [Django-doc]:

from django.db.models import Prefetch

def viewapp(request,pk):
    prodlist = application.objects.filter(
        id=pk, servers__os__startswith='windows'
    ).prefetch_related(
        Prefetch('servers', Server.objects.filter(os__startswith='windows'))
    )

поскольку вы здесь работаете с одним объектом, однако, лучше работать с:

from django.shortcuts import get_object_or_404
from django.db.models import Prefetch

def viewapp(request, pk):
    prod = get_object_or_404(
        application.objects.prefetch_related(
            Prefetch('servers', Server.objects.filter(os__startswith='windows')
        ),
        pk=pk
    )

Здесь prod есть один application объект, а не QuerySet из applications.

Вернуться на верх